home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / unix / shel303a.1 < prev    next >
Internet Message Format  |  1989-05-18  |  64KB

  1. Path: xanth!ames!apple!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i149:  shell - csh-like shell v3.03a, Part01/02
  5. Message-ID: <105698@sun.Eng.Sun.COM>
  6. Date: 18 May 89 19:28:32 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2805
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: PERUGIA@ICNUCEVM.Bitnet (Cesare Dieni)
  12. Posting-number: Volume 89, Issue 149
  13. Archive-name: unix/shell303a.1
  14.  
  15. New to 3.03A:
  16. - New filter commands fltlower, fltupper.
  17. - Added configuration file feature: now if you have a file
  18.   named S:.login, it will be sourced for every Shell you start.
  19. - New option dir -c.
  20. - New editing feature: shift-left(right) arrow move cursor to
  21.   previous(next) word.
  22. - Bugs fixed: alias command wasn't listed in help; typing a number
  23.   as a command was interpreted like 'alias'.
  24.  
  25. # This is a shell archive.
  26. # Remove anything above and including the cut line.
  27. # Then run the rest of the file through 'sh'.
  28. # Unpacked files will be owned by you and have default permissions.
  29. #----cut here-----cut here-----cut here-----cut here----#
  30. #!/bin/sh
  31. # shar: SHell ARchive
  32. # Run the following text through 'sh' to create:
  33. #    comm1.c
  34. #    comm2.c
  35. #    comm3.c
  36. #    execom.c
  37. # This is archive 1 of a 2-part kit.
  38. # This archive created: Thu May 18 12:17:53 1989
  39. echo "extracting comm1.c"
  40. sed 's/^X//' << \SHAR_EOF > comm1.c
  41. X/*
  42. X * COMM1.C
  43. X *
  44. X * Matthew Dillon, August 1986
  45. X *
  46. X * Version 2.07M by Steve Drew 10-Sep-87
  47. X *
  48. X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89
  49. X *
  50. X */
  51. X
  52. Xextern char *v_passed, *v_gotofwd, *v_cwd, *v_lasterr;
  53. X
  54. X#define DIR_SHORT 0x01
  55. X#define DIR_FILES 0x02
  56. X#define DIR_DIRS  0x04
  57. X#define DIR_NOCOL 0x08
  58. X
  59. Xextern int has_wild;
  60. Xchar cwd[256];
  61. X
  62. X/*
  63. X    Parse the options specified in sw[]
  64. X    Setting a bit in global variable options
  65. X    for each one found
  66. X*/
  67. X
  68. Xget_opt(sw,count)
  69. Xchar *sw;
  70. Xint *count;
  71. X{
  72. Xregister char *c,*s;
  73. Xunsigned int l,i = 0;
  74. X
  75. Xoptions=0;
  76. Xwhile((++i < ac) && (av[i][0] == '-')) {
  77. X    for (c = av[i]+1; *c ; c++) {
  78. X        for(l = 0,s = sw;*s && *s != *c; ++s) ++l;
  79. X        if (*s) options |= (1 << l);
  80. X        }
  81. X    }
  82. X*count = i;
  83. X}
  84. X
  85. Xdo_sleep()
  86. X{
  87. Xint i;
  88. X
  89. Xif (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i-=2) Delay(100L);
  90. Xreturn 0;
  91. X}
  92. X
  93. Xdo_protect()
  94. X{
  95. Xregister long mask=0xf;
  96. Xregister char *s, *p, *flags="DEWRAPSH";
  97. Xregister unsigned int i;
  98. Xfor (s=av[--ac]; *s; s++)
  99. X    if (p=index(flags,Toupper(*s))) mask^=(1 << (p-flags));
  100. X    else ierror(av[ac],500);
  101. Xfor (i=1; i<ac; i++) if (!SetProtection(av[i],mask)) pError(av[i]);
  102. Xreturn 0;
  103. X}
  104. X
  105. Xdo_filenote()
  106. X{
  107. Xchar *note=av[--ac];
  108. Xregister unsigned int i;
  109. X
  110. Xfor (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
  111. Xreturn 0;
  112. X}
  113. X
  114. Xdo_cat()
  115. X{
  116. XFILE *fopen(), *fi;
  117. Xregister unsigned int lctr;
  118. Xunsigned int i;
  119. Xchar buf[256];
  120. X
  121. Xget_opt("n",&i);
  122. Xif (i>=ac) {
  123. X    if (has_wild) { printf("No files matching\n"); return 20; }
  124. X    lctr=0;
  125. X    while (gets(buf) && !dobreak()) {
  126. X        if (options) printf("%4d ",++lctr);
  127. X        puts(buf);
  128. X        }
  129. X    }
  130. Xfor (; i<ac; i++)
  131. X    if (fi = fopen (av[i], "r")) {
  132. X        lctr=0;
  133. X        while (fgets(buf,256,fi) && !dobreak()) {
  134. X            if (options) printf("%4d ",++lctr);
  135. X            printf("%s",buf);
  136. X            }
  137. X        fclose (fi);
  138. X        }
  139. X    else pError(av[i]);
  140. Xreturn 0;
  141. X}
  142. X
  143. Xdo_info()
  144. X{
  145. XBPTR lock;
  146. Xstruct InfoData *info;
  147. Xunsigned int size, free;
  148. Xchar *p,*s,*state;
  149. Xstruct DirectoryEntry *de_head=NULL, *de;
  150. X
  151. Xinfo=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC);
  152. XAddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  153. XMyprocess->pr_WindowPtr = (APTR)(-1);
  154. Xprintf ("Unit  Size  Bytes  Used Blk/By-Free Full Errs  Status    Name\n");
  155. Xfor (de=de_head; de; de=de->de_Next) {
  156. X    printf("%-5s",de->de_Name);
  157. X    if (lock=Lock(de->de_Name,ACCESS_READ)) {
  158. X        if (Info(lock, info)) {
  159. X        s = get_pwd(lock);
  160. X        if (p=index(s,':')) *p = '\0';
  161. X        size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock)/ 1024;
  162. X        free = (((info->id_NumBlocks-info->id_NumBlocksUsed))*
  163. X               info->id_BytesPerBlock)/ 1024;
  164. X        switch(info->id_DiskState) {
  165. X            case ID_WRITE_PROTECTED: state="Read Only "; break;
  166. X            case ID_VALIDATED:     state="Read/Write"; break;
  167. X            case ID_VALIDATING:     state="Validating"; break;
  168. X            }
  169. X        printf("%4d%c%6ld%7ld%7ld%4d%c%4ld%%%4ld  %s %s\n",
  170. X            (size>1024) ? ((size+512) >> 10) : size,
  171. X            (size>1024) ? 'M' : 'K',
  172. X            info->id_BytesPerBlock,
  173. X            info->id_NumBlocksUsed,
  174. X            info->id_NumBlocks-info->id_NumBlocksUsed,
  175. X            (free>1024) ? ((free+512) >> 10) : free,
  176. X            (free>1024) ? 'M' : 'K',
  177. X            (info->id_NumBlocksUsed * 100)/info->id_NumBlocks,
  178. X            info->id_NumSoftErrors,
  179. X            state,
  180. X            s);
  181. X        }
  182. X        else pError (de->de_Name);
  183. X        UnLock(lock);
  184. X        }
  185. X    else puts("  No disk present");
  186. X    }
  187. XFreeDAList(&de_head);
  188. XMyprocess->pr_WindowPtr = NULL;
  189. XFreeMem(info,(long)sizeof(struct InfoData));
  190. Xreturn 0;
  191. X}
  192. X
  193. X/* things shared with display_file */
  194. X
  195. Xchar lspec[128];
  196. Xint filecount, col;
  197. Xlong bytes, blocks;
  198. X
  199. X/*
  200. X * the args passed to do_dir will never be expanded
  201. X */
  202. Xdo_dir()
  203. X{
  204. X   void display_file();
  205. X   int i;
  206. X
  207. X   col = filecount = 0;
  208. X   bytes = blocks = 0L;
  209. X   *lspec = '\0';
  210. X
  211. X   get_opt("sfdc",&i);
  212. X
  213. X   if (ac == i) {
  214. X      ++ac;
  215. X      av[i] = "";
  216. X   }
  217. X   if (!(options & (DIR_FILES | DIR_DIRS)))  options|=(DIR_FILES | DIR_DIRS);
  218. X
  219. X   for (; i < ac && !CHECKBREAK(); ++i) {
  220. X      char **eav;
  221. X      int c,eac;
  222. X      if (!(eav = expand(av[i], &eac))) continue;
  223. X      QuickSort(eav, eac);
  224. X      for(c=0;c < eac && !breakcheck();++c) display_file(options,eav[c]);
  225. X      free_expand (eav);
  226. X   }
  227. X   if (col)  printf("\n");
  228. X   if (filecount > 1) {
  229. X      blocks += filecount; /* account for dir blocks */
  230. X      printf (" %ld Blocks, %ld Bytes used in %d files\n", blocks, bytes, filecount);
  231. X   }
  232. X   return 0;
  233. X}
  234. X
  235. Xvoid
  236. Xdisplay_file(options,filestr)
  237. Xint options;
  238. Xchar *filestr;
  239. X{
  240. X   long atol();
  241. X   int isadir,slen;
  242. X   char sc;
  243. X   char *c,*s,*fi;
  244. X   BPTR lock;
  245. X
  246. X/*    if current dir different from lspec then
  247. X    look for ':' or '/' if found lock it and get_pwd.
  248. X    else then use cwd.
  249. X*/
  250. X   for(s = c = filestr; *c; ++c) if (*c == ':' || *c == '/') s = c;
  251. X   if (*s == ':') ++s;
  252. X   sc = *s;
  253. X   *s = '\0';
  254. X   c = filestr;
  255. X   if (!*c) c = cwd;
  256. X   if (strcmp (c, &lspec))  {
  257. X    strcpy(lspec, c);
  258. X    if (col) printf("\n");
  259. X    if (lock=Lock(c,SHARED_LOCK)) {
  260. X        printf("Directory of %s\n", get_pwd(lock));
  261. X        UnLock(lock);
  262. X        }
  263. X    col = 0;
  264. X    }
  265. X   *s = sc;
  266. X   if (sc == '/') s++;
  267. X   slen = strlen(s);
  268. X   fi = s + slen + 1;
  269. X   isadir = (fi[12] =='D');
  270. X
  271. X   if (!(((options & DIR_FILES) && !isadir) ||
  272. X      ((options & DIR_DIRS) &&  isadir)))
  273. X      return;
  274. X   if (isadir && !(options & DIR_NOCOL)) printf ("\23333m");
  275. X   if (options & DIR_SHORT) {
  276. X    if (col==3 && slen>18) { printf("\n"); col = 0; }
  277. X    if (slen>18) { printf(" %-37s",s); col+= 2; }
  278. X        else { printf(" %-18s",s); col++; }
  279. X    if (col > 3) { printf("\n"); col=0; }
  280. X    }
  281. X   else printf("   %-24s %s",s ,fi);
  282. X   if (isadir && !(options & DIR_NOCOL)) printf("\2330m");
  283. X   fflush(stdout);
  284. X   fi[16] = fi[21] = '\0';
  285. X   bytes  += atol(fi+10);
  286. X   blocks += atol(fi+17);
  287. X   filecount++;
  288. X   return;
  289. X}
  290. X
  291. Xdo_quit()
  292. X{
  293. Xif (Src_stack) {
  294. X    Quit = 1;
  295. X    return(do_return());
  296. X    }
  297. Xmain_exit(0);
  298. X}
  299. X
  300. Xdo_echo(str)
  301. Xregister char *str;
  302. X{
  303. Xchar nl=1;
  304. X
  305. Xfor (; *str && *str != ' '; ++str);
  306. Xif (*str==' ') ++str;
  307. Xif (av[1] && !strcmp(av[1],"-n")) {
  308. X    nl = 0;
  309. X    str += 2;
  310. X    if (*str==' ') ++str;
  311. X    }
  312. Xprintf("%s",str);
  313. Xif (nl) printf("\n");
  314. Xfflush(stdout);
  315. Xreturn 0;
  316. X}
  317. X
  318. X/* gets a line from file, joining two lines if the first ends in '\' */
  319. X
  320. Xchar *myfgets(buf, buflen, file)
  321. Xchar *buf;
  322. XFILE *file;
  323. X{
  324. Xchar *bufptr=buf;
  325. Xint remain=buflen, n, flag;
  326. X
  327. Xdo {
  328. X    if (fgets(bufptr, remain, file)==NULL) {
  329. X        if (remain != buflen)
  330. X            fprintf(stderr,"Source: file ends in '\\'\n");
  331. X        return NULL;
  332. X        }
  333. X    n=strlen(buf);
  334. X    bufptr += n;
  335. X    if (flag= (*(bufptr-2)=='\\')) bufptr-=2;
  336. X    remain -= (n+2);
  337. X    } while (flag);
  338. Xreturn buf;
  339. X}
  340. X
  341. Xdo_source(str)
  342. Xchar *str;
  343. X{
  344. Xregister FILE *fi;
  345. Xchar buf[256];
  346. X
  347. Xif (Src_stack == MAXSRC) {
  348. X    ierror(NULL,217);
  349. X    return -1;
  350. X    }
  351. Xif ((fi = fopen (av[1], "r")) == 0) { pError(av[1]); return -1;    }
  352. Xset_var(LEVEL_SET, v_passed, next_word(next_word(str)));
  353. X++H_stack;
  354. XSrc_pos[Src_stack] = 0;
  355. XSrc_base[Src_stack] = (long)fi;
  356. X++Src_stack;
  357. Xwhile (myfgets (buf, 256, fi) && !dobreak()) {
  358. X    int len = strlen(buf);
  359. X    buf[len-1] = '\0';
  360. X    Src_pos[Src_stack - 1] += len;
  361. X    if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf);
  362. X    exec_command (buf);
  363. X    }
  364. X--H_stack;
  365. X--Src_stack;
  366. Xif (forward_goto) ierror(NULL,501);
  367. Xforward_goto = 0;
  368. Xunset_level(LEVEL_LABEL + Src_stack);
  369. Xunset_var(LEVEL_SET, v_gotofwd);
  370. Xunset_var(LEVEL_SET, v_passed);
  371. Xfclose (fi);
  372. Xreturn 0;
  373. X}
  374. X
  375. X/*
  376. X * return ptr to string that contains full cwd spec.
  377. X */
  378. Xchar *get_pwd(flock)
  379. XBPTR flock;
  380. X{
  381. Xstatic char pwdstr[130];
  382. XPathName(flock, pwdstr, 128L);
  383. Xreturn pwdstr;
  384. X}
  385. X
  386. X/*
  387. X * set process cwd name and $_cwd, if str != NULL also print it.
  388. X */
  389. Xdo_pwd(str)
  390. Xchar *str;
  391. X{
  392. Xif (Myprocess->pr_CurrentDir == 0)
  393. X    attempt_cd(":"); /* if we just booted 0 = root lock */
  394. Xstrcpy(cwd,get_pwd(Myprocess->pr_CurrentDir,1));
  395. Xif (str) puts(cwd);
  396. Xset_var(LEVEL_SET, v_cwd, cwd);
  397. X/* put the current dir name in our CLI task structure */
  398. XCtoBStr(cwd, Mycli->cli_SetName, 128L);
  399. X}
  400. X
  401. X/*
  402. X * CD
  403. X *
  404. X * CD(str, 0)      -do CD operation.
  405. X *
  406. X *    standard operation: breakup path by '/'s and process independantly
  407. X *    x:    -reset cwd base
  408. X *    ..    -remove last cwd element
  409. X *    N     -add N or /N to cwd
  410. X */
  411. X
  412. Xdo_cd(str)
  413. Xchar *str;
  414. X{
  415. X   char sc, *ptr;
  416. X   int err=0;
  417. X
  418. X   str = next_word(str);
  419. X   if (*str == '\0') {
  420. X      puts(cwd);
  421. X      return(0);
  422. X   }
  423. X   str[strlen(str)+1] = '\0';        /* add second \0 on end */
  424. X   while (*str) {
  425. X      for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr);
  426. X      switch (*ptr) {
  427. X      case ':':
  428. X      sc = ptr[1];
  429. X      ptr[1] = '\0';
  430. X      err = attempt_cd(str);
  431. X      ptr[1] = sc;
  432. X      break;
  433. X      case '\0':
  434. X      case '/':
  435. X      *ptr = '\0';
  436. X      if (strcmp(str, "..") == 0 || str == ptr)
  437. X         str = "/";
  438. X      if (*str) err = attempt_cd(str);
  439. X      break;
  440. X      }
  441. X      if (err) break;
  442. X      str = ptr + 1;
  443. X   }
  444. X   do_pwd(NULL);      /* set $_cwd */
  445. X   return err;
  446. X}
  447. X
  448. Xattempt_cd(str)
  449. Xchar *str;
  450. X{
  451. XBPTR oldlock, filelock;
  452. X
  453. Xif (filelock=Lock(str, ACCESS_READ)) {
  454. X    if (isdir(str)) {
  455. X        if (oldlock=CurrentDir(filelock)) UnLock(oldlock);
  456. X        return (0);
  457. X        }
  458. X    UnLock(filelock);
  459. X    ierror(str, 212);
  460. X    }
  461. Xelse ierror(str, 205);
  462. Xreturn -1;
  463. X}
  464. X
  465. Xdo_mkdir()
  466. X{
  467. Xregister unsigned int i;
  468. XBPTR lock;
  469. X
  470. Xfor (i=1; i<ac; ++i) {
  471. X    if (exists(av[i])) ierror(av[i],203);
  472. X    else if (lock=CreateDir(av[i])) UnLock (lock);
  473. X    else pError(av[i]);
  474. X    }
  475. Xreturn 0;
  476. X}
  477. X
  478. Xdo_mv()
  479. X{
  480. Xchar *dest, buf[256];
  481. Xint dirflag;
  482. Xregister unsigned int i;
  483. X
  484. Xdirflag=isdir(dest=av[--ac]);
  485. Xif (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
  486. Xfor (i=1; i<ac; ++i) {
  487. X    strcpy(buf, dest);
  488. X    if (dirflag) TackOn(buf, BaseName(av[i]));
  489. X    if (Rename(av[i], buf)==0)
  490. X        { pError(av[i]); return -1; }
  491. X    }
  492. Xreturn 0;
  493. X}
  494. X
  495. Xint dirstoo;
  496. X
  497. Xall_args(args, action, dirsflag)
  498. Xchar *args;
  499. Xint (*action)();
  500. X{
  501. Xunsigned int i;
  502. X
  503. Xget_opt(args, &i);
  504. Xdirstoo=dirsflag;
  505. Xfor (; i<ac && !dobreak(); ++i)
  506. X    if (isdir(av[i])) {
  507. X        if (options & 1) recurse(av[i], action);
  508. X            else if (dirstoo) (*action)(av[i]);
  509. X        }
  510. X    else (*action)(av[i]);
  511. Xreturn 0;
  512. X}
  513. X
  514. Xchar *searchstring;
  515. X
  516. Xsearch_file(s)
  517. Xchar *s;
  518. X{
  519. XFILE *fopen(), *fi;
  520. Xunsigned int lctr, len=strlen(searchstring);
  521. Xint yesno;
  522. Xchar buf[256], lowbuf[256], first;
  523. Xregister char *p, *l, *t;
  524. X
  525. Xif (!(options & 2)) for (t=searchstring; *t=Toupper(*t); t++);
  526. Xfirst=*searchstring;
  527. Xif ((fi=fopen(s, "r"))==NULL) { pError(s); return; }
  528. Xlctr=0;
  529. Xif (!(options & 32)) printf("Examining %s...\n",s);
  530. Xwhile (fgets(buf,256,fi) && !dobreak()) {
  531. X    lctr++;
  532. X    if (options & 4) yesno=compare_ok(searchstring,buf);
  533. X    else {
  534. X        yesno=0;
  535. X        p=buf;
  536. X        if (!(options & 2)) {
  537. X            l=lowbuf;            /* p is already =buf */
  538. X            while (*l++=Toupper(*p++));    /* lowbuf=upper(buf) */
  539. X            p=lowbuf;
  540. X            }
  541. X        while (p=index(p,first))
  542. X            if (!strncmp(p++,searchstring,len)) { yesno=1; break; }
  543. X        }
  544. X    if (yesno ^ ((options & 16)!=0) ) {
  545. X            /* default: print line numbers */
  546. X        if (!(options & 8)) printf("%4d ",lctr);
  547. X        printf("%s",buf);
  548. X        }
  549. X    }
  550. Xfclose (fi);
  551. X}
  552. X
  553. Xdo_search()
  554. X{
  555. Xsearchstring=av[--ac];
  556. Xall_args("rcwneq", search_file, 0);
  557. Xreturn 0;
  558. X}
  559. X
  560. Xrm_file(file)
  561. Xchar *file;
  562. X{
  563. Xif (has_wild) printf(" %s...",file);
  564. Xif (options & 2) SetProtection(file,0L);
  565. Xif (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n");
  566. X}
  567. X
  568. Xdo_rm()
  569. X{
  570. Xall_args("rp", rm_file, 1);
  571. Xreturn 0;
  572. X}
  573. X
  574. Xrecurse(name, action)
  575. Xchar *name;
  576. Xint (*action)();
  577. X{
  578. Xregister BPTR lock, cwd;
  579. Xregister FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC);
  580. Xchar *namecopy=malloc(256);
  581. X
  582. Xif (name[0] =='\0') return;
  583. Xnamecopy[0]=0;
  584. Xif (lock=Lock(name,ACCESS_READ)) {
  585. X    cwd =CurrentDir(lock);
  586. X    if (Examine(lock, fib))
  587. X    while (ExNext(lock, fib) && !CHECKBREAK()) {
  588. X        if (*namecopy) { (*action)(namecopy); namecopy[0]=0; }
  589. X        if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action);
  590. X        else strcpy(namecopy,fib->fib_FileName);
  591. X        }
  592. X    if (*namecopy) (*action)(namecopy);
  593. X    UnLock(CurrentDir(cwd));
  594. X    if (dirstoo) (*action)(name);
  595. X    }
  596. Xelse pError(name);
  597. Xfree(namecopy);
  598. XFreeMem(fib, (long)sizeof(FIB));
  599. X}
  600. X
  601. Xdo_history()
  602. X{
  603. Xregister struct HIST *hist;
  604. Xint i = H_tail_base;
  605. Xint len = (av[1]) ? strlen(av[1]) : 0;
  606. X
  607. Xfor (hist = H_tail; hist && !dobreak(); hist = hist->prev)
  608. X    if (len == 0 || !strncmp(av[1], hist->line, len))
  609. X        printf("%3d %s\n", i++, hist->line);
  610. Xreturn 0;
  611. X}
  612. X
  613. Xdo_mem()
  614. X{
  615. Xlong cfree, ffree;
  616. Xextern long AvailMem();
  617. X
  618. XForbid();
  619. Xcfree = AvailMem (MEMF_CHIP);
  620. Xffree = AvailMem (MEMF_FAST);
  621. XPermit();
  622. Xif (ffree) printf ("FAST memory: %ld\nCHIP memory: %ld\n", ffree, cfree);
  623. Xprintf("Total  Free: %ld\n", cfree+ffree);
  624. Xreturn 0;
  625. X}
  626. X
  627. X/* forline i RAM:temp echo line $_linenum: $i */
  628. X
  629. Xdo_forline()
  630. X{
  631. Xchar vname[33], buf[256];
  632. Xregister unsigned short lctr;
  633. XFILE *f;
  634. Xchar *cstr;
  635. Xstatic char *linenumname="_linenum";
  636. X
  637. Xstrcpy(vname,av[1]);
  638. Xf=fopen(av[2],"r");
  639. Xif (f==NULL) pError(av[2]);
  640. Xlctr=0;
  641. X++H_stack;
  642. Xcstr = compile_av (av, 3, ac, ' ');
  643. Xwhile (fgets(buf,256,f) && !dobreak()) {
  644. X    buf[strlen(buf)-1]='\0';    /* remove CR */
  645. X    lctr++;
  646. X    set_var(LEVEL_SET, vname, buf);
  647. X    sprintf(buf,"%d",lctr);
  648. X    set_var(LEVEL_SET, linenumname, buf);
  649. X    exec_command(cstr);
  650. X    }
  651. Xfclose(f);
  652. X--H_stack;
  653. Xfree (cstr);
  654. Xunset_var (LEVEL_SET, vname);
  655. Xunset_var (LEVEL_SET, linenumname);
  656. Xreturn 0;
  657. X}
  658. X
  659. X/* fornum i 1 10 echo $i */
  660. X
  661. Xdo_fornum()
  662. X{
  663. Xchar vname[33], buf[16];
  664. Xint n1, n2;
  665. Xchar *cstr;
  666. Xregister int i;
  667. X
  668. Xstrcpy(vname,av[1]);
  669. Xn1=myatoi(av[2],0 ,32767); if (Errno) return 20;
  670. Xn2=myatoi(av[3],n1,    32767); if (Errno) return 20;
  671. X++H_stack;
  672. Xcstr = compile_av (av, 4, ac, ' ');
  673. Xfor (i=n1; i<=n2 && !CHECKBREAK(); i++) {
  674. X    sprintf(buf,"%d",i);
  675. X    set_var (LEVEL_SET, vname, buf);
  676. X    exec_command(cstr);
  677. X    }
  678. X--H_stack;
  679. Xfree (cstr);
  680. Xunset_var (LEVEL_SET, vname);
  681. Xreturn 0;
  682. X}
  683. X
  684. X/*
  685. X * foreach var_name  ( str str str str... str ) commands
  686. X * spacing is important (unfortunately)
  687. X *
  688. X * ac=0    1 2 3 4 5 6 7
  689. X * foreach i ( a b c ) echo $i
  690. X * foreach i ( *.c ) "echo -n "file ->";echo $i"
  691. X */
  692. X
  693. Xdo_foreach()
  694. X{
  695. Xregister int cstart, cend;
  696. Xregister char *cstr;
  697. Xchar **fav;
  698. Xchar vname[33];
  699. Xint i;
  700. X
  701. Xget_opt("v",&i);
  702. Xstrcpy(vname, av[i++]);
  703. Xif (*av[i] == '(') i++;
  704. Xcstart = i;
  705. Xwhile (i<ac && *av[i] != ')') i++;
  706. Xif (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
  707. X++H_stack;
  708. Xcend = i;
  709. X
  710. Xfav = (char **)malloc(sizeof(char *) * (ac));
  711. Xcstr = compile_av (av, cend + 1, ac, ' ');
  712. X
  713. Xfor (i = cstart; i < cend; ++i) fav[i] = av[i];
  714. X
  715. Xfor (i = cstart; i<cend && !CHECKBREAK(); ++i) {
  716. X    set_var (LEVEL_SET, vname, fav[i]);
  717. X    if (options & 1) printf("foreach: %s\n", fav[i]);
  718. X    exec_command(cstr);
  719. X    }
  720. X--H_stack;
  721. Xfree (fav);
  722. Xfree (cstr);
  723. Xunset_var (LEVEL_SET, vname);
  724. Xreturn 0;
  725. X}
  726. X
  727. Xdo_forever(str)
  728. Xchar *str;
  729. X{
  730. Xint rcode = 0;
  731. Xchar *ptr = next_word(str);
  732. X
  733. X++H_stack;
  734. Xfor (;;) {
  735. X    if (CHECKBREAK()) { rcode = 20; break; }
  736. X    if (exec_command (ptr) < 0) {
  737. X        str = get_var(LEVEL_SET, v_lasterr);
  738. X        rcode = (str) ? atoi(str) : 20;
  739. X        break;
  740. X        }
  741. X    }
  742. X--H_stack;
  743. Xreturn rcode;
  744. X}
  745. X
  746. Xdo_exec(str)
  747. Xchar *str;
  748. X{
  749. Xreturn exec_command(next_word(str));
  750. X}
  751. X
  752. Xextern struct Window *w;
  753. Xextern struct IntuitionBase *IntuitionBase;
  754. X
  755. Xdo_window()
  756. X{
  757. Xlong x, y, maxwidth, maxheight, arg[5];
  758. Xunsigned int i;
  759. Xstruct Screen *screen;
  760. Xstruct Window *window;
  761. X
  762. Xget_opt("slfbaq", &i);
  763. Xif (options & 1)
  764. X    SizeWindow(w, (long)(w->MinWidth-w->Width), (long)(w->MinHeight-w->Height));
  765. Xif (options & 2) {
  766. X    x=-w->LeftEdge;
  767. X    y=-w->TopEdge;
  768. X    MoveWindow(w,x,y);
  769. X    x=IntuitionBase->ActiveScreen->Width -w->Width;
  770. X    y=IntuitionBase->ActiveScreen->Height-w->Height;
  771. X    SizeWindow(w,x,y);
  772. X    }
  773. Xif (options & 4) WindowToFront(w);
  774. Xif (options & 8) WindowToBack(w);
  775. Xif (options & 16) ActivateWindow(w);
  776. Xif(ac >= 5) {
  777. X    for(i=1; i<5; i++) {
  778. X        arg[i] = myatoi(av[i],0,1023);
  779. X        if (Errno) return 20;
  780. X        }
  781. X    maxwidth = w->WScreen->Width;
  782. X    maxheight= w->WScreen->Height;
  783. X    if (arg[3] > maxwidth - arg[1] || arg[4] > maxheight- arg[2]) {
  784. X        ierror(NULL, 500);
  785. X        return 20;
  786. X        }
  787. X    x = -w->LeftEdge;
  788. X    y = -w->TopEdge;
  789. X    MoveWindow(w, x, y);
  790. X    x = arg[3] - w->Width;
  791. X    y = arg[4] - w->Height;
  792. X    SizeWindow(w, x, y);
  793. X    x = arg[1];
  794. X    y = arg[2];
  795. X    MoveWindow(w, x, y);
  796. X    }
  797. Xif(options & 32) {
  798. X    for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen) {
  799. X        printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
  800. X            screen->Title,
  801. X            screen->LeftEdge,
  802. X            screen->TopEdge,
  803. X            screen->Width,
  804. X            screen->Height
  805. X            );
  806. X        for (window=screen->FirstWindow; window; window=window->NextWindow) {
  807. X        printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
  808. X            window->Title,
  809. X            window->LeftEdge,
  810. X            window->TopEdge,
  811. X            window->Width,
  812. X            window->Height
  813. X            );
  814. X        }
  815. X        }
  816. X    return 0;
  817. X    }
  818. XDelay(25L); /* pause 1/2 sec. before trying to print */
  819. Xprintf("\014");
  820. Xreturn 0;
  821. X}
  822. X
  823. Xsetsystemtime(ds)
  824. Xstruct DateStamp *ds;
  825. X{
  826. Xstruct timerequest tr;
  827. Xlong secs= ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  828. X
  829. Xif (OpenDevice(TIMERNAME, UNIT_VBLANK, &tr, 0L)) {
  830. X    fprintf(stderr,"Clock error: can't open timer device\n");
  831. X    return;
  832. X    }
  833. Xtr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  834. Xtr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
  835. Xtr.tr_node.io_Message.mn_Node.ln_Name = NULL;
  836. Xtr.tr_node.io_Message.mn_ReplyPort = NULL;
  837. Xtr.tr_node.io_Command = TR_SETSYSTIME;
  838. Xtr.tr_time.tv_secs = secs;
  839. Xtr.tr_time.tv_micro = 0L;
  840. Xif (DoIO (&tr)) fprintf(stderr,"Clock error: can't talk to timer device\n");
  841. XCloseDevice (&tr);
  842. X}
  843. X
  844. Xchar tday[10];
  845. X
  846. Xchar *dates(dss)
  847. Xstruct DateStamp *dss;
  848. X{
  849. Xstatic char timestr[40];
  850. Xchar tdate[10], ttime[10];
  851. Xstruct DateTime dt;
  852. Xstruct DateStamp *myds=&(dt.dat_Stamp);
  853. X
  854. Xdt.dat_Format=FORMAT_DOS;
  855. Xdt.dat_StrDay=tday;
  856. Xdt.dat_StrDate=tdate;
  857. Xdt.dat_StrTime=ttime;
  858. Xdt.dat_Flags=NULL;
  859. Xmyds->ds_Days=dss->ds_Days;
  860. Xmyds->ds_Minute=dss->ds_Minute;
  861. Xmyds->ds_Tick=dss->ds_Tick;
  862. XStamptoStr(&dt);
  863. Xsprintf(timestr,"%s %s\n",tdate,ttime);
  864. Xtimestr[18]='\n';
  865. Xtimestr[19]='\0';    /* protection against bad timestamped files */
  866. Xreturn timestr;
  867. X}
  868. X
  869. Xdate()
  870. X{
  871. Xstruct DateStamp dss;
  872. Xregister unsigned short i;
  873. Xstruct DateTime dt;
  874. X
  875. Xdt.dat_Format=FORMAT_DOS;
  876. Xif (ac==1) {
  877. X    DateStamp(&dss);
  878. X    printf("%s %s",tday,dates(&dss));
  879. X    }
  880. Xelse {
  881. X    DateStamp(& (dt.dat_Stamp));
  882. X    for (i=1; i<ac; i++) {
  883. X        dt.dat_StrDate=NULL;
  884. X        dt.dat_StrTime=NULL;
  885. X        dt.dat_Flags=DTF_FUTURE;
  886. X        if (index(av[i],':')) dt.dat_StrTime=av[i];
  887. X            else dt.dat_StrDate=av[i];
  888. X        if (StrtoStamp(&dt)) ierror(av[i],500);
  889. X        }
  890. X    setsystemtime( & (dt.dat_Stamp) );
  891. X    }
  892. Xreturn 0;
  893. X}
  894. SHAR_EOF
  895. echo "extracting comm2.c"
  896. sed 's/^X//' << \SHAR_EOF > comm2.c
  897. X/*
  898. X * COMM2.C
  899. X *
  900. X * (c)1986 Matthew Dillon     9 October 1986
  901. X *
  902. X * Version 2.07M by Steve Drew 10-Sep-87
  903. X *
  904. X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89
  905. X *
  906. X */
  907. X
  908. Xextern char *v_gotofwd;
  909. X
  910. X/* Casting conveniences */
  911. X#define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
  912. X#define PROC(task)              ((struct Process *)task)
  913. X#define CLI(proc)               (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
  914. X
  915. X/* Externs */
  916. Xextern int has_wild;                    /* flag set if any arg has a ? or * */
  917. X
  918. X/* globals */
  919. Xint cp_update;
  920. Xint cp_date;
  921. X
  922. Xdo_abortline()
  923. X{
  924. XExec_abortline = 1;
  925. Xreturn 0;
  926. X}
  927. X
  928. Xdo_return()
  929. X{
  930. Xregister int retcode=(ac<2 ? 0 : atoi(av[1]));
  931. X   Exec_abortline = 1;
  932. X   if (Src_stack) {
  933. X       FILE *ptr = (FILE *)Src_base[Src_stack - 1];
  934. X       ptr->_bp = ptr->_bend;
  935. X       ptr->_flags |= _EOF;
  936. X/*     fseek (Src_base[Src_stack - 1], 0L, 2); */
  937. X      return retcode;
  938. X   } else main_exit(retcode);
  939. X}
  940. X
  941. X/*
  942. X * STRHEAD
  943. X *
  944. X * place a string into a variable removing everything after and including
  945. X * the 'break' character
  946. X *
  947. X * strhead varname breakchar string
  948. X *
  949. X */
  950. X
  951. Xdo_strhead()
  952. X{
  953. Xchar *s;
  954. Xif (s=index(av[3],*av[2])) *s='\0';
  955. Xset_var (LEVEL_SET, av[1], av[3]);
  956. Xreturn 0;
  957. X}
  958. X
  959. Xdo_strtail()
  960. X{
  961. Xchar *s;
  962. Xif (s=index(av[3],*av[2])) s++; else s=av[3];
  963. Xset_var (LEVEL_SET, av[1], s);
  964. Xreturn 0;
  965. X}
  966. X
  967. Xlong dptrtosecs(d)
  968. Xstruct DPTR *d;
  969. X{
  970. Xregister struct DateStamp *ds=(&d->fib->fib_Date);
  971. Xreturn ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  972. X}
  973. X
  974. Xlong timeof(s)
  975. Xchar *s;
  976. X{
  977. Xstruct DPTR *d;
  978. Xint dummy;
  979. Xlong n;
  980. X
  981. Xif ( (d=dopen(s,&dummy))==NULL ) return 0L;
  982. Xn=dptrtosecs(d);
  983. Xdclose(d);
  984. Xreturn n;
  985. X}
  986. X
  987. X/*
  988. X * if -f file (exists) or:
  989. X *
  990. X * if A < B   <, >, =, <=, >=, <>, where A and B are either:
  991. X * nothing
  992. X * a string
  993. X * a value (begins w/ number)
  994. X */
  995. X
  996. Xdo_if(garbage, com)
  997. Xchar *garbage;
  998. X{
  999. Xint result;
  1000. Xint i;
  1001. X
  1002. Xswitch (com) {
  1003. X    case 0:
  1004. X    if (If_stack && If_base[If_stack - 1]) If_base[If_stack++] = 1;
  1005. X    else {
  1006. X        get_opt("rftmdn",&i);
  1007. X        result=evalif(i);
  1008. X        If_base[If_stack++]=(options & 32 ? result : !result);
  1009. X        }
  1010. X    break;
  1011. X    case 1:
  1012. X    if (If_stack > 1 && If_base[If_stack - 2]) break;
  1013. X    if (If_stack) If_base[If_stack - 1] ^= 1;
  1014. X    break;
  1015. X    case 2:
  1016. X    if (If_stack) --If_stack;
  1017. X    break;
  1018. X     }
  1019. Xdisable = (If_stack) ? If_base[If_stack - 1] : 0;
  1020. Xif (If_stack >= MAXIF) {
  1021. X    fprintf(stderr,"If's too deep\n");
  1022. X    disable = If_stack = 0;
  1023. X    return -1;
  1024. X    }
  1025. Xif (forward_goto) disable = If_base[If_stack - 1] = 0;
  1026. Xreturn 0;
  1027. X}
  1028. X
  1029. Xevalif(i)
  1030. Xregister unsigned int i;
  1031. X{
  1032. Xchar c;
  1033. Xlong num, t0;
  1034. Xlong AvailMem();
  1035. X
  1036. Xswitch(options & ~32) {
  1037. X    case 0:
  1038. X    if (ac-i != 3) return (ac>i && *av[i]);
  1039. X    Errno=0;
  1040. X    num=Atol(av[i])-Atol(av[i+2]);
  1041. X    if (Errno) num=strcmp(av[i],av[i+2]);
  1042. X    if (num < 0)       c='<';
  1043. X    else if (num > 0)  c='>';
  1044. X    else if (num == 0) c='=';
  1045. X    return index(av[i+1], c) != NULL;
  1046. X    case 1:
  1047. X    return do_rpn(NULL,i);
  1048. X    case 2:
  1049. X    return exists(av[i]);
  1050. X    case 4:
  1051. X    t0=timeof(av[i++]);
  1052. X    for ( ; i<ac ; i++)
  1053. X        if (t0<=timeof(av[i])) return 1;
  1054. X    return 0;
  1055. X    case 8:
  1056. X    return (AvailMem( (long)MEMF_FAST )!=0);
  1057. X    case 16:
  1058. X    return (isdir(av[i])!=0);
  1059. X    default:
  1060. X    ierror(NULL,500);
  1061. X    return 0;
  1062. X    }
  1063. X}
  1064. X
  1065. Xdo_label()
  1066. X{
  1067. X   char aseek[32];
  1068. X
  1069. X   if (Src_stack == 0) {
  1070. X      ierror (NULL, 502);
  1071. X      return (-1);
  1072. X   }
  1073. X
  1074. X   sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
  1075. X   set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
  1076. X   if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd)))
  1077. X      forward_goto = 0;
  1078. X   return 0;
  1079. X}
  1080. X
  1081. Xdo_goto()
  1082. X{
  1083. X   int new;
  1084. X   long pos;
  1085. X   char *lab;
  1086. X
  1087. X   if (Src_stack == 0) {
  1088. X      ierror (NULL, 502);
  1089. X   } else {
  1090. X      lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
  1091. X      if (lab == NULL) {
  1092. X         forward_goto = 1;
  1093. X         set_var (LEVEL_SET, v_gotofwd, av[1]);
  1094. X         return(0);
  1095. X      } else {
  1096. X         pos = atoi(lab);
  1097. X         fseek (Src_base[Src_stack - 1], pos, 0);
  1098. X         Src_pos[Src_stack - 1] = pos;
  1099. X         new = atoi(next_word(lab));
  1100. X         for (; If_stack < new; ++If_stack)
  1101. X            If_base[If_stack] = 0;
  1102. X         If_stack = new;
  1103. X      }
  1104. X   }
  1105. X   Exec_abortline = 1;
  1106. X   return (0);      /* Don't execute rest of this line */
  1107. X}
  1108. X
  1109. X
  1110. Xdo_inc(garbage, com)
  1111. Xchar *garbage;
  1112. X{
  1113. Xchar *var, num[32];
  1114. X
  1115. Xif (ac>2) com *= atoi(av[2]);
  1116. Xif (var = get_var (LEVEL_SET, av[1])) {
  1117. X    sprintf (num, "%d", atoi(var)+com);
  1118. X    set_var (LEVEL_SET, av[1], num);
  1119. X    }
  1120. Xreturn 0;
  1121. X}
  1122. X
  1123. Xdo_input()
  1124. X{
  1125. Xchar in[256], *p,*s;
  1126. Xunsigned int i;
  1127. X
  1128. Xfor (i=1; i < ac; ++i)
  1129. X    if (gets(in)) {
  1130. X    for(p = in; *p; p = s) {
  1131. X        s = next_word(p);
  1132. X        if (*s) *(s-1) = 0xA0;
  1133. X        }
  1134. X    set_var (LEVEL_SET, av[i], in);
  1135. X    }
  1136. Xreturn 0;
  1137. X}
  1138. X
  1139. Xdo_ver()
  1140. X{
  1141. Xputs("Shell V3.03A\n\
  1142. X)1986 Matthew Dillon\n\
  1143. XManx (M) versions by Steve Drew\n\
  1144. XARP (A) versions by Carlo Borreo & Cesare Dieni\n");
  1145. Xreturn 0;
  1146. X}
  1147. X
  1148. Xdo_ps()
  1149. X{
  1150. X/* this code fragment based on ps.c command by Dewi Williams */
  1151. X
  1152. Xregister int    count;        /* loop variable        */
  1153. Xstruct Task    *task;        /* EXEC descriptor        */
  1154. Xchar        strbuf[64+1];    /* scratch for btocstr()    */
  1155. Xchar        cmd[40+1];    /* holds cmd name        */
  1156. Xlong ncli;
  1157. X
  1158. Xprintf("Proc Command Name         CLI Type    Pri.  Address  Directory\n");
  1159. XForbid();
  1160. X
  1161. Xncli=(long)FindCLI(0L);
  1162. Xfor (count = 1; count <= ncli ; count++)
  1163. X        /* or just assume 20?*/
  1164. X    if (task = (struct Task *)FindCLI((long)count)) {
  1165. X    if (task==NULL) continue;
  1166. X    /* Sanity check just in case */
  1167. X    if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue;
  1168. X                            /* or complain? */
  1169. X    BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
  1170. X    BtoCStr(strbuf,CLI(PROC(task))->cli_SetName    , 64L);
  1171. X    printf("%2d   %-20.20s %-11.11s %3d  %8lx  %s\n",
  1172. X        count,
  1173. X        cmd,
  1174. X        task->tc_Node.ln_Name,
  1175. X        task->tc_Node.ln_Pri,
  1176. X        task,
  1177. X        strbuf);
  1178. X    }
  1179. XPermit();
  1180. Xreturn 0;
  1181. X}
  1182. X
  1183. X/*
  1184. X * CP [-d] [-u] file file
  1185. X * CP [-d] [-u] file file file... destdir
  1186. X * CP [-r][-u][-d] dir dir dir... destdir
  1187. X */
  1188. X
  1189. Xchar *errstr;          /* let's be alittle more informative */
  1190. X
  1191. Xdo_copy()
  1192. X{
  1193. Xregister int recur, ierr;
  1194. Xregister char *destname;
  1195. Xregister char destisdir;
  1196. Xregister FIB *fib;
  1197. Xint i;
  1198. X
  1199. Xerrstr = "";
  1200. Xierr = 0;
  1201. X
  1202. Xfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1203. X
  1204. Xget_opt("rud",&i);
  1205. Xrecur     = (options & 0x01);
  1206. Xcp_update = (options & 0x02);
  1207. Xcp_date   = (!(options & 0x04)); /* the default is keep orignal file date */
  1208. X
  1209. Xdestname = av[ac - 1];
  1210. X
  1211. Xif (ac < i + 2) {
  1212. X    ierr = 500;
  1213. X    goto done;
  1214. X    }
  1215. Xdestisdir = isdir(destname);
  1216. Xif (ac > i + 2 && !destisdir) {
  1217. X    ierr = 507;
  1218. X    goto done;
  1219. X    }
  1220. X
  1221. X/*
  1222. X * copy set:                        reduce to:
  1223. X *    file to file                     file to file
  1224. X *    dir  to file (NOT ALLOWED)
  1225. X *    file to dir                      dir to dir
  1226. X *    dir  to dir                      dir to dir
  1227. X *
  1228. X */
  1229. X
  1230. Xfor (; i<ac-1 && !dobreak(); ++i) {
  1231. X    short srcisdir = isdir(av[i]);
  1232. X    if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
  1233. X        continue;             /* getting copied if specified */
  1234. X                         /* from wild expansion */
  1235. X    if (srcisdir) {
  1236. X        BPTR srcdir, destdir;
  1237. X        if (!destisdir) {
  1238. X            if (exists(destname)) {
  1239. X                ierr = 507;    /* disallow dir to file */
  1240. X                goto done;
  1241. X                }
  1242. X            if (destdir = CreateDir(destname)) UnLock(destdir);
  1243. X            destisdir = 1;
  1244. X            }
  1245. X        if (!(destdir = Lock(destname, ACCESS_READ))) {
  1246. X            ierr = 205;
  1247. X            errstr = destname;
  1248. X            goto done;
  1249. X            }
  1250. X        if (!(srcdir = Lock(av[i], ACCESS_READ))) {
  1251. X            ierr = 205;
  1252. X            errstr = av[i];
  1253. X            UnLock(destdir);
  1254. X            goto done;
  1255. X            }
  1256. X        ierr = copydir(srcdir, destdir, recur);
  1257. X        UnLock(srcdir);
  1258. X        UnLock(destdir);
  1259. X        if (ierr) break;
  1260. X        }
  1261. X    else {        /* FILE to DIR,   FILE to FILE   */
  1262. X        BPTR destdir, srcdir, tmp;
  1263. X        char *destfilename;
  1264. X
  1265. X        srcdir = (BPTR)(Myprocess->pr_CurrentDir);
  1266. X
  1267. X        if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) {
  1268. X            if (tmp) UnLock(tmp);
  1269. X            ierr = 205;
  1270. X            errstr = av[i];
  1271. X            goto done;
  1272. X            }
  1273. X        UnLock(tmp);
  1274. X        if (destisdir) {
  1275. X            destdir = Lock(destname, ACCESS_READ);
  1276. X            destfilename = fib->fib_FileName;
  1277. X            }
  1278. X        else {
  1279. X            destdir = srcdir;
  1280. X            destfilename = destname;
  1281. X            }
  1282. X        printf(" %s..",av[i]);
  1283. X        fflush(stdout);
  1284. X        ierr = copyfile(av[i], srcdir, destfilename, destdir);
  1285. X        if (destisdir) UnLock(destdir);
  1286. X        if (ierr) break;
  1287. X        }
  1288. X    }
  1289. X
  1290. Xdone:
  1291. X
  1292. XFreeMem(fib, (long)sizeof(FIB));
  1293. Xif (ierr) {
  1294. X    ierror(errstr, ierr);
  1295. X    return(20);
  1296. X    }
  1297. Xreturn 0;
  1298. X}
  1299. X
  1300. X
  1301. Xcopydir(srcdir, destdir, recur)
  1302. Xregister BPTR srcdir, destdir;
  1303. X{
  1304. X   BPTR cwd;
  1305. X   register FIB *srcfib;
  1306. X   register BPTR destlock, srclock;
  1307. X   int ierr;
  1308. X   static int level;
  1309. X
  1310. X   level++;
  1311. X   ierr = 0;
  1312. X   srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1313. X   if (Examine(srcdir, srcfib)) {
  1314. X      while (ExNext(srcdir, srcfib)) {
  1315. X         if (CHECKBREAK())
  1316. X            break;
  1317. X         if (srcfib->fib_DirEntryType < 0) {
  1318. X            printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
  1319. X            fflush(stdout);
  1320. X            ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
  1321. X            if (ierr)
  1322. X               break;
  1323. X         } else {
  1324. X            if (recur) {
  1325. X               cwd = CurrentDir(srcdir);
  1326. X               if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) {
  1327. X                  CurrentDir(destdir);
  1328. X                  if (!(destlock = Lock(srcfib->fib_FileName))) {
  1329. X                     destlock = CreateDir(srcfib->fib_FileName);
  1330. X                     printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
  1331. X                                " ",srcfib->fib_FileName);
  1332. X
  1333. X                        /* UnLock and re Lock if newly created
  1334. X                           for file_date() to work properly
  1335. X                        */
  1336. X                     if (destlock) UnLock(destlock);
  1337. X                     destlock = Lock(srcfib->fib_FileName);
  1338. X                  }
  1339. X                  else
  1340. X                     printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
  1341. X                  if (destlock) {
  1342. X                     ierr = copydir(srclock, destlock, recur);
  1343. X                     UnLock(destlock);
  1344. X                  } else {
  1345. X                     ierr = (int)((long)IoErr());
  1346. X                  }
  1347. X                  UnLock(srclock);
  1348. X               } else {
  1349. X                  ierr = (int)((long)IoErr());
  1350. X               }
  1351. X               CurrentDir(cwd);
  1352. X               if (ierr)
  1353. X                  break;
  1354. X            }
  1355. X         }
  1356. X      }
  1357. X   } else {
  1358. X      ierr = (int)((long)IoErr());
  1359. X   }
  1360. X   --level;
  1361. X   FreeMem(srcfib, (long)sizeof(FIB));
  1362. X   return(ierr);
  1363. X}
  1364. X
  1365. X
  1366. Xcopyfile(srcname, srcdir, destname, destdir)
  1367. Xchar *srcname, *destname;
  1368. XBPTR srcdir, destdir;
  1369. X{
  1370. XBPTR cwd;
  1371. XBPTR f1, f2;
  1372. Xlong i;
  1373. Xint stat,ierr;
  1374. Xchar *buf;
  1375. Xstruct DPTR *dp, *dps = NULL;
  1376. X
  1377. Xif ((buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  1378. X    { ierr = 103; goto fail; }
  1379. Xierr = 0;
  1380. Xcwd = CurrentDir(srcdir);
  1381. Xif ((f1=Open(srcname, MODE_OLDFILE))==NULL)
  1382. X    { errstr = srcname; ierr = 205; goto fail; }
  1383. Xdps = dopen(srcname,&stat);
  1384. XCurrentDir(destdir);
  1385. Xif (cp_update)
  1386. X    {
  1387. X    dp=dopen(destname, &stat);
  1388. X    if ( dptrtosecs(dp) >= dptrtosecs(dps) &&
  1389. X        !strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName))
  1390. X        { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; }
  1391. X    dclose(dp);
  1392. X    }
  1393. Xif ((f2=Open(destname, MODE_NEWFILE))==NULL)
  1394. X    { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail;  }
  1395. Xwhile (i = Read(f1, buf, 8192L))
  1396. X    if (Write(f2, buf, i) != i) { ierr = (int)((long)IoErr()); break; }
  1397. XClose(f2);
  1398. XClose(f1);
  1399. Xif (!ierr)
  1400. X    {
  1401. X    if (cp_date) file_date(&dps->fib->fib_Date, destname);
  1402. X    printf("..copied\n");
  1403. X    }
  1404. Xelse DeleteFile(destname);
  1405. Xfail:
  1406. X dclose(dps);
  1407. X if (buf) FreeMem(buf, 8192L);
  1408. X CurrentDir(cwd);
  1409. X return(ierr);
  1410. X}
  1411. X
  1412. Xdo_touch()
  1413. X{
  1414. Xstruct DateStamp ds;
  1415. Xregister unsigned int i;
  1416. XDateStamp(&ds);
  1417. Xfor (i=1; i<ac; i++) if (file_date(&ds, av[i])) ierror(av[i],500);
  1418. Xreturn 0;
  1419. X}
  1420. X
  1421. Xfile_date(date,name)
  1422. Xstruct DateStamp *date;
  1423. Xchar *name;
  1424. X{
  1425. Xlong packargs[7];
  1426. XUBYTE *ptr;
  1427. Xstruct MsgPort *task;
  1428. XBPTR dirlock;
  1429. Xstruct DPTR *tmp;
  1430. Xint stat;
  1431. X
  1432. Xif (!(task = (struct MsgPort *)DeviceProc(name))) return(1);
  1433. Xif (tmp = dopen(name, &stat)) {
  1434. X    dirlock = ParentDir(tmp->lock);
  1435. X    ptr=AllocMem(65L,MEMF_PUBLIC);
  1436. X    CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L);
  1437. X    dclose(tmp);
  1438. X    packargs[1]=dirlock;
  1439. X    packargs[2]=(ULONG)ptr >> 2L;
  1440. X    packargs[3]=(long)date;
  1441. X    SendPacket(ACTION_SET_DATE,packargs,task);
  1442. X    UnLock(dirlock);
  1443. X    FreeMem(ptr,65L);
  1444. X    }
  1445. Xreturn 0;
  1446. X}
  1447. X
  1448. Xdo_addbuffers()
  1449. X{
  1450. Xlong packargs[7];
  1451. Xlong n;
  1452. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1453. X
  1454. Xif (!task) { ierror(av[1],510); return 20; }
  1455. Xn=myatoi(av[2],1,32767); if (Errno) return 20;
  1456. Xpackargs[0]=n;
  1457. XSendPacket(ACTION_MORE_CACHE,packargs,task);
  1458. Xreturn 0;
  1459. X}
  1460. X
  1461. Xdo_relabel()
  1462. X{
  1463. Xlong packargs[7];
  1464. XUBYTE *ptr;
  1465. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1466. X
  1467. Xif (!task) { ierror(av[1],510); return 20; }
  1468. Xptr=AllocMem(65L,MEMF_PUBLIC);
  1469. XCtoBStr(av[2],(ULONG)ptr >> 2L,64L);
  1470. Xpackargs[0]=(ULONG)ptr >> 2L;
  1471. XSendPacket(ACTION_RENAME_DISK,packargs,task);
  1472. XFreeMem(ptr,65L);
  1473. Xchangedisk(task);
  1474. Xreturn 0;
  1475. X}
  1476. X
  1477. Xdo_diskchange()
  1478. X{
  1479. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1480. X
  1481. Xif (!task) { ierror(av[1],510); return 20; }
  1482. Xchangedisk(task);
  1483. Xreturn 0;
  1484. X}
  1485. X
  1486. Xchangedisk(task)
  1487. Xstruct MsgPort *task;
  1488. X{
  1489. Xlong packargs[7];
  1490. X
  1491. Xpackargs[0]=1L;
  1492. XSendPacket(ACTION_INHIBIT,packargs,task);
  1493. Xpackargs[0]=0L;
  1494. XSendPacket(ACTION_INHIBIT,packargs,task);
  1495. X}
  1496. SHAR_EOF
  1497. echo "extracting comm3.c"
  1498. sed 's/^X//' << \SHAR_EOF > comm3.c
  1499. X/*
  1500. X * COMM3.C
  1501. X *
  1502. X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89
  1503. X *
  1504. X */
  1505. X
  1506. Xdo_assign() {
  1507. Xswitch(ac) {
  1508. X    case 1:  assignlist();
  1509. X         break;
  1510. X    case 2:  doassign(av[1], NULL);
  1511. X         break;
  1512. X    case 3:  doassign(av[1], av[2]);
  1513. X         break;
  1514. X    default: ierror(NULL, 500);
  1515. X         break;
  1516. X    }
  1517. Xreturn 0;
  1518. X}
  1519. X
  1520. Xchar *assign_errors[4]={
  1521. X    "",
  1522. X    "Name %s is not valid\n",
  1523. X    "Weird error\n",
  1524. X    "Can't cancel %s\n"
  1525. X    };
  1526. X
  1527. Xdoassign(log, phy)
  1528. Xchar *log, *phy;
  1529. X{
  1530. Xint last=strlen(log) - 1;
  1531. X
  1532. Xif (log[last] != ':') fprintf(stderr, "Bad name %s\n", log);
  1533. Xelse {
  1534. X    log[last] = 0;
  1535. X    fprintf(stderr,assign_errors[Assign(log, phy)],log);
  1536. X    }
  1537. X}
  1538. X
  1539. Xassignlist()
  1540. X{
  1541. Xstruct DirectoryEntry *de_head=NULL, *de;
  1542. Xchar buf[256];
  1543. XBPTR lock;
  1544. Xint ctr=0;
  1545. X
  1546. XAddDADevs(&de_head, DLF_DEVICES | DLF_VOLUMES | DLF_DIRS);
  1547. Xprintf("Devices:\n");
  1548. Xfor (de=de_head; de && de->de_Type==DLX_DEVICE; de=de->de_Next) {
  1549. X    printf("%-8s",de->de_Name);
  1550. X    if (ctr++ == 5) { ctr=0; printf("\n"); }
  1551. X    }
  1552. Xprintf("\n\nVolumes:\n");
  1553. Xfor (    ;
  1554. X    de && (de->de_Type==DLX_VOLUME || de->de_Type==DLX_UNMOUNTED);
  1555. X    de=de->de_Next
  1556. X    )
  1557. X    printf( "%-16s %s\n",
  1558. X        de->de_Name,
  1559. X        de->de_Type == DLX_VOLUME ? "[Mounted]" : ""
  1560. X        );
  1561. Xprintf("\nDirectories:\n");
  1562. Xfor (; de && de->de_Type==DLX_ASSIGN; de=de->de_Next) {
  1563. X    if (lock=Lock(de->de_Name, ACCESS_READ)) {
  1564. X        PathName(lock, buf, 256L);
  1565. X        UnLock(lock);
  1566. X        }
  1567. X    else
  1568. X        strcpy(buf,"Unexisting lock");
  1569. X    printf("%-20s%s\n",de->de_Name,buf);
  1570. X    }
  1571. XFreeDAList(&de_head);
  1572. X}
  1573. X
  1574. Xdo_join()
  1575. X{
  1576. XBPTR sou, dest;
  1577. Xchar *buffer;
  1578. Xunsigned int i;
  1579. Xlong n;
  1580. Xchar *namedest=av[--ac];
  1581. X
  1582. Xget_opt("r", &i);
  1583. Xif (options==0 && exists(namedest)) { ierror(namedest,203); return 20; }
  1584. Xif ( (buffer=malloc(8192)) == NULL ) { ierror(NULL,103); return 20; }
  1585. Xif ( (dest=Open(namedest, MODE_NEWFILE)) == NULL )
  1586. X    { pError(namedest); goto fail1; }
  1587. Xfor (i=1; i<ac; i++) {
  1588. X    if ( (sou=Open(av[i], MODE_OLDFILE)) == NULL ) pError(av[i]);
  1589. X    else
  1590. X        while( (n=Read(sou, buffer, 8192L)) > 0 )
  1591. X            if (Write(dest, buffer, n) != n)
  1592. X                { pError(namedest); Close(sou); goto fail2; }
  1593. X    Close(sou);
  1594. X    }
  1595. Xfail2:
  1596. X    Close(dest);
  1597. Xfail1:
  1598. X    free(buffer);
  1599. X    return 0;
  1600. X}
  1601. X
  1602. X#define BUFDIM 512L
  1603. X#define MAXSTR 256
  1604. X
  1605. Xint minstr;
  1606. X
  1607. Xstrings_in_file(s)
  1608. Xchar *s;
  1609. X{
  1610. Xchar c;
  1611. Xchar readbuf[BUFDIM+1], strbuf[MAXSTR+1];
  1612. Xregister unsigned int i, strctr=0;
  1613. XBPTR fh;
  1614. Xint out, n;
  1615. X
  1616. Xif ( fh=Open(s, MODE_OLDFILE) ) {
  1617. X    fprintf(stderr, "Strings in %s (len>=%d):\n",s,minstr);
  1618. X    while ( (n=(int)Read(fh, readbuf, BUFDIM)) > 0 && !CHECKBREAK() )
  1619. X        for (i=0; i<n; i++) {
  1620. X        c=readbuf[i];
  1621. X        if (c<0x20 || c>0x7f) {
  1622. X            out=(strctr>=minstr);
  1623. X            if (!out) strctr=0;
  1624. X            }
  1625. X        else {
  1626. X            strbuf[strctr++]=c;
  1627. X            out=(strctr>=BUFDIM);
  1628. X            }
  1629. X        if (out) {
  1630. X            strbuf[strctr]='\0';
  1631. X            puts(strbuf);
  1632. X            strctr=0;
  1633. X            }
  1634. X        }
  1635. X    Close(fh);
  1636. X    }
  1637. Xelse pError(s);
  1638. X}
  1639. X
  1640. Xdo_strings()
  1641. X{
  1642. Xminstr=myatoi(av[--ac],1,255);
  1643. Xall_args("r", strings_in_file, 0);
  1644. Xreturn 0;
  1645. X}
  1646. X
  1647. XBPTR myfile[MAXMYFILES];
  1648. X
  1649. Xdo_open()
  1650. X{
  1651. Xlong mode;
  1652. Xunsigned int n;
  1653. X
  1654. Xswitch (av[2][0]) {
  1655. X    case 'r': mode=MODE_OLDFILE; break;
  1656. X    case 'w': mode=MODE_NEWFILE; break;
  1657. X    default : ierror(NULL,500); return;
  1658. X    }
  1659. XErrno=0;
  1660. Xn=(unsigned int)myatoi(av[3],0,MAXMYFILES); if (Errno) return 20;
  1661. Xmyfile[n]=Open(av[1],mode);
  1662. Xreturn (myfile[n]==NULL);
  1663. X}
  1664. X
  1665. Xdo_close()
  1666. X{
  1667. Xregister unsigned int i;
  1668. Xint n;
  1669. X
  1670. Xfor (i=1; i<ac; i++) {
  1671. X    Errno=0;
  1672. X    n=myatoi(av[i],0,MAXMYFILES); if (Errno) return 20;
  1673. X    myclose(n);
  1674. X    }
  1675. Xreturn 0;
  1676. X}
  1677. X
  1678. Xmyclose(n)
  1679. X{
  1680. Xif (myfile[n]) { Close(myfile[n]); myfile[n]=NULL; }
  1681. X}
  1682. X
  1683. Xdo_fileslist()
  1684. X{
  1685. Xregister unsigned short i;
  1686. Xint flag=0;
  1687. X
  1688. Xprintf("Open files:");
  1689. Xfor (i=0; i<MAXMYFILES; i++)
  1690. X    if (myfile[i]) { printf(" %d",i); flag=1; }
  1691. Xif (!flag) printf(" None!");
  1692. Xprintf("\n");
  1693. Xreturn 0;
  1694. X}
  1695. X
  1696. XBPTR extOpen(name,mode)
  1697. Xchar *name;
  1698. Xlong mode;
  1699. X{
  1700. Xif (name[0]=='.') return myfile[atoi(name+1)];
  1701. Xreturn Open(name,mode);
  1702. X}
  1703. X
  1704. XextClose(fh)
  1705. XBPTR fh;
  1706. X{
  1707. Xregister unsigned short i;
  1708. X
  1709. Xfor (i=0; i<MAXMYFILES; i++)
  1710. X    if (myfile[i]==fh) return;
  1711. XClose(fh);
  1712. X}
  1713. X
  1714. Xdo_resident(avline)
  1715. Xchar *avline;
  1716. X{
  1717. Xunsigned int i;
  1718. XBPTR seg;
  1719. Xstruct ResidentPrgNode *p;
  1720. X
  1721. Xget_opt("ar", &i);
  1722. Xswitch (options) {
  1723. X    case 0:
  1724. X    ObtainSemaphore (& (ArpBase->ResPrgProtection) );
  1725. X    if (p=ArpBase->ResidentPrgList) {
  1726. X        printf("Name             Users\n");
  1727. X        for (; p; p=p->rpn_Next)
  1728. X            printf("%-16s %-3ld\n",p->rpn_Name,p->rpn_Usage);
  1729. X        }
  1730. X    else printf("No resident program(s)\n");
  1731. X    ReleaseSemaphore(& (ArpBase->ResPrgProtection) );
  1732. X    break;
  1733. X    case 1:
  1734. X    for (; i<ac; i++)
  1735. X        if ( (seg=(BPTR)LoadPrg(av[i])) && AddResidentPrg(seg,av[i]) )
  1736. X            printf("OK! %s is now resident\n", BaseName(av[i]));
  1737. X        else pError(av[i]);
  1738. X    break;
  1739. X    case 2:
  1740. X    for (; i<ac; i++)
  1741. X        if (RemResidentPrg(av[i])) ierror(av[i],202);
  1742. X        else printf("Removed %s\n",av[i]);
  1743. X    break;
  1744. X    default:
  1745. X    ierror(NULL,500);
  1746. X    break;
  1747. X    }
  1748. Xreturn 0;
  1749. X}
  1750. X
  1751. Xstruct ProcessControlBlock pcb={
  1752. X    4000,        /* pcb_StackSize    */
  1753. X    0,        /* pcb_Pri        */
  1754. X    };
  1755. X/* remaining field are NULL */
  1756. X    
  1757. Xdo_truerun(avline, backflag)
  1758. Xchar *avline;
  1759. X{
  1760. Xchar name[200];
  1761. Xchar *FindIt();
  1762. X
  1763. Xif (backflag) {
  1764. X    pcb.pcb_Control=NULL;
  1765. X    pcb.pcb_Input=pcb.p_Output=Open("NIL:",MODE_OLDFILE);
  1766. X    }
  1767. Xelse {
  1768. X    pcb.pcb_Control=NULL;
  1769. X    pcb.pcb_Input=pcb.p_Output =NULL;
  1770. X    }
  1771. Xif (FindIt(av[1], "", name))
  1772. X    ASyncRun(name,next_word(next_word(avline)),&pcb);
  1773. Xelse
  1774. X    ierror(av[1],205);
  1775. Xreturn 0;
  1776. X}
  1777. X
  1778. Xint exists(name)
  1779. Xchar *name;
  1780. X{
  1781. XBPTR lock;
  1782. X
  1783. Xif (lock=Lock(name,ACCESS_READ)) {
  1784. X    UnLock(lock);
  1785. X    return 1;
  1786. X    }
  1787. Xreturn 0;
  1788. X}
  1789. X
  1790. Xdo_aset()
  1791. X{
  1792. XSetenv(av[1],av[2]);
  1793. Xreturn 0;
  1794. X}
  1795. X
  1796. X#define HTYPELINE 16L
  1797. X
  1798. Xhtype_a_file(s)
  1799. Xchar *s;
  1800. X{
  1801. XBPTR fh;
  1802. Xlong n, filesize=0;
  1803. Xchar buf[HTYPELINE+1];
  1804. Xregister unsigned int i;
  1805. X
  1806. Xif ( (fh=Open(s,MODE_OLDFILE))==NULL ) { pError(s); return 20; }
  1807. Xwhile ( (n=Read(fh,buf,HTYPELINE))>0 && !dobreak()) {
  1808. X    printf("%06lx: ",filesize);
  1809. X    filesize+=n;
  1810. X    for (i=0; i<n; i++) {
  1811. X        printf( (i&3) ? "%02x" : " %02x",(int)(unsigned char)buf[i]);
  1812. X        if (buf[i]<=0x20) buf[i]='.';
  1813. X        }
  1814. X    for ( ; i<HTYPELINE; i++) {
  1815. X        printf( (i&3) ? "  " : "   ");
  1816. X        buf[i]=' ';
  1817. X        }
  1818. X    buf[i]=0;
  1819. X    printf("    %s\n",buf);
  1820. X    }
  1821. XClose(fh);
  1822. Xreturn 0;
  1823. X}
  1824. X
  1825. Xdo_htype()
  1826. X{
  1827. Xall_args("", htype_a_file, 0);
  1828. Xreturn 0;
  1829. X}
  1830. X
  1831. Xdo_stack()
  1832. X{
  1833. Xlong n;
  1834. X
  1835. Xif (ac>1) {
  1836. X    Errno=0;
  1837. X    n=Atol(av[1]);
  1838. X    if (!Errno) Mycli->cli_DefaultStack=(long)(n >> 2L);
  1839. X    }
  1840. Xelse printf("current stack size is %ld bytes\n",
  1841. X                (long)Mycli->cli_DefaultStack << 2L);
  1842. Xreturn 0;
  1843. X}
  1844. X
  1845. Xdo_fault()
  1846. X{
  1847. Xstruct PERROR *p;
  1848. Xregister unsigned int i;
  1849. Xint n;
  1850. X
  1851. Xfor (i=1; i<ac; i++) {
  1852. X    n=myatoi(av[i],0,32767);
  1853. X    if (!Errno) {
  1854. X        for (p=Perror; p->errnum && p->errnum!=n; p++);
  1855. X        if (p->errnum)
  1856. X            printf("Fault %d: %s\n",n,p->errstr);
  1857. X        else
  1858. X            printf("Fault %d not recognized\n",n);
  1859. X        }
  1860. X    }
  1861. Xreturn 0;
  1862. X}
  1863. X
  1864. Xstruct rpncommand {
  1865. X    char *str;
  1866. X    int parsin, parsout;
  1867. X    };
  1868. X
  1869. Xstruct rpncommand rpn[]={
  1870. X    "+",    2,    1,
  1871. X    "-",    2,    1,
  1872. X    "*",    2,    1,
  1873. X    "/",    2,    1,
  1874. X    "%",    2,    1,
  1875. X    "&",    2,    1,
  1876. X    "|",    2,    1,
  1877. X    "~",    1,    1,
  1878. X    ">",    2,    1,
  1879. X    "<",    2,    1,
  1880. X    "==",    2,    1,
  1881. X    "!",    1,    1,
  1882. X    "DUP",    1,    2,
  1883. X    "DROP",    1,    0,
  1884. X    "SWAP",    2,    2,
  1885. X    "HELP",    0,    0,
  1886. X    NULL,    0,    1,    /* this looks for a number */
  1887. X};
  1888. X
  1889. Xdo_rpn(garbage,ifflag) /* ifflag!=0 if called from if */
  1890. Xchar *garbage;
  1891. X{
  1892. Xregister long n0, n1;
  1893. Xlong t;
  1894. Xunsigned int i, j;
  1895. Xint sp=0;
  1896. Xlong stack[100];
  1897. Xstruct rpncommand *temp;
  1898. X
  1899. Xi=1;
  1900. Xif (ifflag) get_opt("rn",&i);
  1901. Xfor (; i<ac; i++) {
  1902. X    for (j=0; rpn[j].str && Strcmp(rpn[j].str,av[i]); j++) ;
  1903. X    n0=stack[sp-1];
  1904. X    n1=stack[sp-2];
  1905. X    sp -= (rpn[j].parsin);
  1906. X    if (sp<0) { fprintf(stderr, "RPN: Empty stack\n"); return 1; }
  1907. X    switch (j) {
  1908. X      case 0:    n0 += n1;        break;
  1909. X      case 1:    n0 = n1-n0;        break;
  1910. X      case 2:    n0 *= n1;        break;
  1911. X      case 3:    n0 = n1/n0;        break;
  1912. X      case 4:    n0 = n1%n0;        break;
  1913. X      case 5:    n0 &= n1;        break;
  1914. X      case 6:    n0 |= n1;        break;
  1915. X      case 7:    n0 =  ~n0;        break;
  1916. X      case 8:    n0 = (n1 > n0);        break;
  1917. X      case 9:    n0 = (n1 < n0);        break;
  1918. X      case 10:    n0 = (n0 == n1);    break;
  1919. X      case 11:    n0 = !n0;        break;
  1920. X      case 12:    n1=n0;            break;
  1921. X      case 13:    t=n0; n0=n1; n1=t;    break;
  1922. X      case 14:                break;
  1923. X      case 15:    printf("In Commands Out\n");
  1924. X            for (temp=rpn; temp->str; temp++)
  1925. X                printf(" %d %-10s%d\n",
  1926. X                temp->parsin,temp->str,temp->parsout);
  1927. X            break;
  1928. X      default:    Errno=0;
  1929. X            n0=Atol(av[i]);
  1930. X            if (Errno) {
  1931. X                fprintf(stderr, "Bad RPN cmd: %s\n",av[i]);
  1932. X                return 20;
  1933. X                }
  1934. X            break;
  1935. X      }
  1936. X    stack[sp]=n0;
  1937. X    stack[sp+1]=n1;
  1938. X    sp += rpn[j].parsout;
  1939. X    }
  1940. Xif (ifflag) return (int)(stack[sp-1]);    /* called from if: return top value */
  1941. Xfor (i=sp-1;(int)i>=0;i--) printf("%ld\n", stack[i]); /* else print stack */
  1942. Xreturn 0;
  1943. X}
  1944. X
  1945. Xdo_path()
  1946. X{
  1947. Xunion {    long *lp; long ll; } l;
  1948. Xchar buf[256];
  1949. X
  1950. Xputs("Current dir");
  1951. Xl.lp = (long *) Mycli->cli_CommandDir;
  1952. Xwhile (l.ll) {
  1953. X    l.ll <<= 2;
  1954. X    PathName(l.lp[1], buf, 256L);
  1955. X    puts(buf);
  1956. X    l.ll = *l.lp;
  1957. X    }
  1958. Xputs("C:");
  1959. Xreturn 0;
  1960. X}
  1961. X
  1962. Xdo_pri()
  1963. X{
  1964. Xint t, pri;
  1965. Xstruct Process *proc;
  1966. X
  1967. Xt=myatoi(av[1],0,20); if (Errno) return 20;
  1968. Xpri=myatoi(av[2],-128,127); if (Errno) return 20;
  1969. XForbid();
  1970. Xproc=(t==0 ? Myprocess : FindCLI((long)t));
  1971. Xif (proc==NULL) fprintf(stderr, "process not found\n");
  1972. X    else SetTaskPri(proc, (long)pri);
  1973. XPermit();
  1974. Xreturn 0;
  1975. X}
  1976. X
  1977. Xdo_strleft()
  1978. X{
  1979. Xchar buf[256];
  1980. Xint n;
  1981. X
  1982. Xstrcpy(buf,av[2]);
  1983. Xn=myatoi(av[3],1,strlen(buf)); if (Errno) return 20;
  1984. Xbuf[n]='\0';
  1985. Xset_var(LEVEL_SET, av[1], buf);
  1986. Xreturn 0;
  1987. X}
  1988. X
  1989. Xdo_strright()
  1990. X{
  1991. Xchar buf[256];
  1992. Xint n;
  1993. X
  1994. Xstrcpy(buf, av[2]);
  1995. Xn=myatoi(av[3],1,strlen(buf)); if (Errno) return 20;
  1996. Xset_var(LEVEL_SET, av[1], buf+strlen(buf)-n);
  1997. Xreturn 0;
  1998. X}
  1999. X
  2000. Xdo_strmid()
  2001. X{
  2002. Xchar buf[256];
  2003. Xint n1, n2;
  2004. X
  2005. Xstrcpy(buf, av[2]);
  2006. Xn1=myatoi(av[3],1,strlen(buf))-1; if (Errno) return 20;
  2007. Xif (ac>4) {
  2008. X    n2=myatoi(av[4],1,strlen(buf)-n1);
  2009. X    if (Errno) return 20;
  2010. X    buf[n1+n2]='\0';
  2011. X    }
  2012. Xset_var(LEVEL_SET, av[1], buf+n1);
  2013. Xreturn 0;
  2014. X}
  2015. X
  2016. Xdo_strlen()
  2017. X{
  2018. Xchar buf[16];
  2019. X
  2020. Xsprintf(buf,"%d",strlen(av[2]));
  2021. Xset_var(LEVEL_SET, av[1], buf);
  2022. Xreturn 0;
  2023. X}
  2024. X
  2025. Xmyatoi(s,min,max)
  2026. Xchar *s;
  2027. X{
  2028. Xlong n;
  2029. X
  2030. XErrno=0;
  2031. Xn=Atol(s);
  2032. Xif (Errno==ERRBADINT) ierror(s,511);
  2033. X    else if (n<min || n>max) {
  2034. X        Errno=ERRBADINT;
  2035. X        printf("%s not in (%d,%d)\n",s,min,max);
  2036. X        }
  2037. Xreturn (int)n;
  2038. X}
  2039. X
  2040. Xdo_fltlower()
  2041. X{
  2042. Xchar buf[256], *s;
  2043. X
  2044. Xwhile (!CHECKBREAK() && gets(buf)) {
  2045. X    for (s=buf; *s; s++) *s=tolower(*s);
  2046. X    puts(buf);
  2047. X    }
  2048. Xreturn 0;
  2049. X}
  2050. X
  2051. Xdo_fltupper()
  2052. X{
  2053. Xchar buf[256], *s;
  2054. X
  2055. Xwhile (!CHECKBREAK() && gets(buf)) {
  2056. X    for (s=buf; *s; s++) *s=toupper(*s);
  2057. X    puts(buf);
  2058. X    }
  2059. Xreturn 0;
  2060. X}
  2061. SHAR_EOF
  2062. echo "extracting execom.c"
  2063. sed 's/^X//' << \SHAR_EOF > execom.c
  2064. X/*
  2065. X * EXECOM.C
  2066. X *
  2067. X * Matthew Dillon, 10 August 1986
  2068. X *    Finally re-written.
  2069. X *
  2070. X * Version 2.07M by Steve Drew 10-Sep-87
  2071. X *
  2072. X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89
  2073. X *
  2074. X */
  2075. X
  2076. Xextern char *v_histnum, *v_except;
  2077. X
  2078. X#define F_EXACT 0
  2079. X#define F_ABBR  1
  2080. X
  2081. X#define ST_COND   0x01
  2082. X#define ST_NORED  0x02
  2083. X#define ST_NOEXP  0x04
  2084. X#define ST_AV     0x08 /* delimit args within a variable */
  2085. X
  2086. Xint has_wild = 0;                 /* set if any arg has wild card */
  2087. X
  2088. Xstruct COMMAND {
  2089. X    int (*func)();
  2090. X    short minargs;
  2091. X    short stat;
  2092. X    int val;
  2093. X    char *name;
  2094. X};
  2095. X
  2096. Xextern char *format_insert_string();
  2097. Xextern char *mpush(), *exarg();
  2098. X
  2099. Xextern int do_fltupper(), do_fltlower();
  2100. Xextern int do_strleft(), do_strright(), do_strmid(), do_strlen();
  2101. Xextern int do_fornum(), do_forline(), do_exec();
  2102. Xextern int do_diskchange(), do_stack(), do_fault(), do_path(), do_pri();
  2103. Xextern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany();
  2104. Xextern int do_open(), do_close(), do_fileslist(), do_htype();
  2105. Xextern int do_run(), do_number(), do_assign(), do_join();
  2106. Xextern int do_quit(), do_set_var(), do_unset_var();
  2107. Xextern int do_echo(), do_source(), do_mv(), do_addbuffers();
  2108. Xextern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history();
  2109. Xextern int do_mem(), do_cat(), do_dir(), do_info(), do_inc();
  2110. Xextern int do_foreach(), do_return(), do_if(), do_label(), do_goto();
  2111. Xextern int do_input(), do_ver(), do_sleep(), do_help();
  2112. Xextern int do_strhead(), do_strtail(), do_relabel();
  2113. Xextern int do_copy(), date(), do_protect(), do_ps();
  2114. Xextern int do_forever(), do_abortline(), do_strings(), do_touch();
  2115. Xextern int do_window(), do_search(), do_filenote();
  2116. Xchar *push_cpy();
  2117. X
  2118. Xstatic struct COMMAND Command[] = {
  2119. Xdo_run,        0, ST_AV,    0,    "\001",   /* may call do_source */
  2120. Xdo_set_var,    0, 0, LEVEL_ALIAS,    "alias",  /* uses avline */
  2121. Xdo_abortline,    0, 0,        0,    "abortline",
  2122. Xdo_addbuffers,    2, 0,        0,    "addbuffers",
  2123. Xdo_aset,    1, 0,        0,    "aset",
  2124. Xdo_assign,    0, 0,        0,    "assign",
  2125. Xdo_cat,        0, 0,        0,    "cat",
  2126. Xdo_cd,        0, 0,        0,    "cd",
  2127. Xdo_close,    0, 0,        0,    "close",
  2128. Xdo_copy,    1, 0,        0,    "copy",
  2129. Xdo_copy,    1, 0,        0,    "cp",
  2130. Xdate,        0, 0,        0,    "date",
  2131. Xdo_rm,        0, 0,        0,    "delete",
  2132. Xdo_dir,        0, ST_NOEXP,    0,    "dir",
  2133. Xdo_diskchange,    1, 0,        0,    "diskchange",
  2134. Xdo_inc,        1, 0,        -1,    "dec",
  2135. Xdo_echo,    0, 0,        0,    "echo", /* uses avline */
  2136. Xdo_if,        0, ST_COND,    1,    "else",
  2137. Xdo_if,        0, ST_COND,    2,    "endif",
  2138. Xdo_exec,    1, 0,        0,    "exec",
  2139. Xdo_fault,    1, 0,        0,    "fault",
  2140. Xdo_filenote,    2, 0,        0,    "filenote",
  2141. Xdo_fileslist,    0, 0,        0,    "flist",
  2142. Xdo_fltlower,    0, 0,        0,    "fltlower",
  2143. Xdo_fltupper,    0, 0,        0,    "fltupper",
  2144. Xdo_foreach,    3, ST_NORED,    0,    "foreach",
  2145. Xdo_forever,    1, ST_NORED,    0,    "forever",
  2146. Xdo_forline,    3, ST_NORED,    0,    "forline",
  2147. Xdo_fornum,    4, ST_NORED,    0,    "fornum",
  2148. Xdo_goto,    1, 0,        0,    "goto",
  2149. Xdo_help,    0, 0,        0,    "help",
  2150. Xdo_history,    0, 0,        0,    "history",
  2151. Xdo_howmany,    0, 0,        0,    "howmany",
  2152. Xdo_htype,    1, 0,        0,    "htype",
  2153. Xdo_if,        1, ST_COND|ST_NORED,0,    "if",
  2154. Xdo_inc,        1, 0,        1,    "inc",
  2155. Xdo_info,    0, 0,        0,    "info",
  2156. Xdo_join,    2, 0,        1,    "join",
  2157. Xdo_input,    1, 0,        0,    "input",
  2158. Xdo_label,    1, ST_COND,    0,    "label",
  2159. Xdo_dir,        0, ST_NOEXP,    0,    "ls",
  2160. Xdo_mkdir,    0, 0,        0,    "md",
  2161. Xdo_mem,        0, 0,        0,    "mem",
  2162. Xdo_mkdir,    0, 0,        0,    "mkdir",
  2163. Xdo_mv,        2, 0,        0,    "mv",
  2164. Xdo_open,    3, 0,        0,    "open",
  2165. Xdo_path,    0, 0,        0,    "path",
  2166. Xdo_pri,        2, 0,        0,    "pri",
  2167. Xdo_protect,    2, 0,        0,    "protect",
  2168. Xdo_ps,        0, 0,        0,    "ps",
  2169. Xdo_pwd,        0, 0,        0,    "pwd",
  2170. Xdo_quit,    0, ST_NORED,    0,    "quit",
  2171. Xdo_truerun,    1, ST_NORED,    1,    "rback",
  2172. Xdo_mv,        2, 0,        0,    "rename",
  2173. Xdo_relabel,    2, 0,        0,    "relabel",
  2174. Xdo_resident,    0, 0,        0,    "resident",
  2175. Xdo_return,    0, 0,        0,    "return",
  2176. Xdo_rm,        0, 0,        0,    "rm",
  2177. Xdo_rpn,        0, ST_NOEXP|ST_NORED,0,    "rpn",
  2178. Xdo_truerun,    1, ST_NORED,    0,    "run",
  2179. Xdo_search,    2, 0,        0,    "search",
  2180. Xdo_set_var,    0, ST_AV, LEVEL_SET,    "set",
  2181. Xdo_sleep,    0, 0,        0,    "sleep",
  2182. Xdo_source,    0, ST_NORED|ST_AV, 0,    "source", /* uses avline */
  2183. Xdo_stack,    0, 0,        0,    "stack",
  2184. Xdo_strhead,    3, 0,        0,    "strhead",
  2185. Xdo_strings,    1, 0,        0,    "strings",
  2186. Xdo_strleft,    3, 0,        0,    "strleft",
  2187. Xdo_strlen,    2, 0,        0,    "strlen",
  2188. Xdo_strmid,    3, 0,        0,    "strmid",
  2189. Xdo_strright,    3, 0,        0,    "strright",
  2190. Xdo_strtail,    3, 0,        0,    "strtail",
  2191. Xdo_touch,    0, 0,        0,    "touch",
  2192. Xdo_cat,        0, 0,        0,    "type",
  2193. Xdo_unset_var,    0, 0, LEVEL_ALIAS,    "unalias",
  2194. Xdo_unset_var,    0, 0, LEVEL_SET  ,    "unset",
  2195. Xdo_ver,        0, 0,        0,    "version",
  2196. Xdo_window,    0, ST_NOEXP,    0,    "window",
  2197. X'\0',        0, 0,        0,    NULL
  2198. X};
  2199. X
  2200. Xstatic unsigned char elast;        /* last end delimeter */
  2201. Xstatic char Cin_ispipe, Cout_ispipe;
  2202. X
  2203. Xexec_command(base)
  2204. Xchar *base;
  2205. X{
  2206. Xregister char *scr;
  2207. Xchar buf[32];
  2208. X
  2209. Xif (!H_stack) {
  2210. X    add_history(base);
  2211. X    sprintf(buf, "%d", H_tail_base + H_len);
  2212. X    set_var(LEVEL_SET, v_histnum, buf);
  2213. X    }
  2214. Xscr = malloc((strlen(base) << 2) + 2);
  2215. Xpreformat(base, scr);
  2216. Xreturn (fcomm(scr, 1) ? -1 : 1);
  2217. X}
  2218. X
  2219. Xisalphanum(c)
  2220. Xregister char c;
  2221. X{
  2222. Xreturn (
  2223. X    (c >= '0' && c <= '9') ||
  2224. X    (c >= 'a' && c <= 'z') ||
  2225. X    (c >= 'A' && c <= 'Z') ||
  2226. X    (c == '_')
  2227. X    );
  2228. X}
  2229. X
  2230. Xpreformat(s, d)
  2231. Xregister char *s, *d;
  2232. X{
  2233. Xregister int si, di, qm;
  2234. X
  2235. Xsi = di = qm = 0;
  2236. Xwhile (s[si] == ' ' || s[si] == 9) ++si;
  2237. Xwhile (s[si]) {
  2238. X    if (qm && s[si] != '\"' && s[si] != '\\') {
  2239. X        d[di++] = s[si++] | 0x80;
  2240. X        continue;
  2241. X        }
  2242. X    switch (s[si]) {
  2243. X        case ' ':
  2244. X        case 9:
  2245. X            d[di++] = ' ';
  2246. X            while (s[si] == ' ' || s[si] == 9) ++si;
  2247. X            if (s[si] == 0 || s[si] == '|' || s[si] == ';') --di;
  2248. X            break;
  2249. X        case '*':
  2250. X        case '?':
  2251. X            d[di++] = 0x80;
  2252. X        case '!':
  2253. X            d[di++] = s[si++];
  2254. X            break;
  2255. X        case '#':
  2256. X            d[di++] = '\0';
  2257. X            while (s[si]) ++si;
  2258. X            break;
  2259. X        case ';':
  2260. X        case '|':
  2261. X            d[di++] = s[si++];
  2262. X            while (s[si] == ' ' || s[si] == 9) ++si;
  2263. X            break;
  2264. X        case '\\':
  2265. X            d[di++] = s[++si] | 0x80;
  2266. X            if (s[si]) ++si;
  2267. X            break;
  2268. X        case '\"':
  2269. X            qm = 1 - qm;
  2270. X            ++si;
  2271. X            break;
  2272. X        case '^':
  2273. X            d[di++] = s[++si] & 0x1F;
  2274. X            if (s[si]) ++si;
  2275. X            break;
  2276. X        case '$': /* search end of var name and place false space */
  2277. X            d[di++] = 0x80;
  2278. X            d[di++] = s[si++];
  2279. X            while (isalphanum(s[si])) d[di++] = s[si++];
  2280. X            d[di++] = 0x80;
  2281. X            break;
  2282. X        default:
  2283. X            d[di++] = s[si++];
  2284. X            break;
  2285. X        }
  2286. X    }
  2287. Xd[di++]=0;
  2288. Xd[di]=0;
  2289. Xif (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d);
  2290. X}
  2291. X
  2292. Xextern BPTR extOpen();
  2293. X
  2294. X/*
  2295. X * process formatted string.  ' ' is the delimeter.
  2296. X *
  2297. X *    0: check '\0': no more, stop, done.
  2298. X *    1: check $.     if so, extract, format, insert
  2299. X *    2: check alias. if so, extract, format, insert. goto 1
  2300. X *    3: check history or substitution, extract, format, insert. goto 1
  2301. X *
  2302. X *    4: assume first element now internal or disk based command.
  2303. X *
  2304. X *    5: extract each ' ' or 0x80 delimited argument and process, placing
  2305. X *       in av[] list (except 0x80 args appended).  check in order:
  2306. X *
  2307. X *             '$'         insert string straight
  2308. X *             '>'         setup stdout
  2309. X *             '>>'        setup stdout flag for append
  2310. X *             '<'         setup stdin
  2311. X *             '*' or '?'  do directory search and insert as separate args.
  2312. X *
  2313. X *             ';' 0 '|'   end of command.  if '|' setup stdout
  2314. X *                          -execute command, fix stdin and out (|) sets
  2315. X *                           up stdin for next guy.
  2316. X */
  2317. X
  2318. X
  2319. Xfcomm(str, freeok)
  2320. Xregister char *str;
  2321. X{
  2322. X   static int alias_count;
  2323. X   int p_alias_count = 0;
  2324. X   char *istr;
  2325. X   char *nextstr;
  2326. X   char *command;
  2327. X   char *pend_alias = NULL;
  2328. X   char err = 0;
  2329. X   has_wild = 0;
  2330. X
  2331. X   ++alias_count;
  2332. X
  2333. X   mpush_base();
  2334. X   if (*str == 0)
  2335. X      goto done1;
  2336. Xstep1:
  2337. X   if (alias_count == MAXALIAS || ++p_alias_count == MAXALIAS) {
  2338. X      fprintf(stderr,"Alias Loop\n");
  2339. X      err = 20;
  2340. X      goto done1;
  2341. X   }
  2342. X/*
  2343. X   if (str[1] == '$') {
  2344. X      if (istr = get_var (LEVEL_SET, str + 2))
  2345. X         str = format_insert_string(str, istr, &freeok);
  2346. X   }
  2347. X*/
  2348. X   istr = NULL;
  2349. X   if (*(unsigned char *)str < 0x80)
  2350. X      istr = get_var (LEVEL_ALIAS, str);  /* only if not \command */
  2351. X   *str &= 0x7F;                          /* remove \ teltail     */
  2352. X   if (istr) {
  2353. X      if (*istr == '%') {
  2354. X         pend_alias = istr;
  2355. X      } else {
  2356. X         str = format_insert_string(str, istr, &freeok);
  2357. X         goto step1;
  2358. X      }
  2359. X   }
  2360. X   if (*str == '!') {
  2361. X      char *p, c;                     /* fix to allow !cmd1;!cmd2 */
  2362. X      for(p = str; *p && *p != ';' ; ++p);
  2363. X      c = *p;
  2364. X      *p = '\0';
  2365. X      istr = get_history(str);
  2366. X      *p = c;
  2367. X      replace_head(istr);
  2368. X      str = format_insert_string(str, istr, &freeok);
  2369. X      goto step1;
  2370. X   }
  2371. X   nextstr = str;
  2372. X   command = exarg(&nextstr);
  2373. X   if (*command == 0)
  2374. X      goto done0;
  2375. X   if (pend_alias == 0) {
  2376. X      if (cmd_stat(command) & ST_COND)
  2377. X         goto skipgood;
  2378. X   }
  2379. X   if (disable || forward_goto) {
  2380. X      while (elast && elast != ';' && elast != '|')
  2381. X         exarg(&nextstr);
  2382. X      goto done0;
  2383. X   }
  2384. Xskipgood:
  2385. X   {
  2386. X      register char *arg, *ptr, *scr;
  2387. X      short redir;
  2388. X      short doexpand;
  2389. X      short cont;
  2390. X      short inc;
  2391. X
  2392. X      ac = 1;
  2393. X      av[0] = command;
  2394. Xstep5:                                          /* ac = nextac */
  2395. X      if (!elast || elast == ';' || elast == '|')
  2396. X         goto stepdone;
  2397. X
  2398. X      av[ac] = '\0';
  2399. X      cont = 1;
  2400. X      doexpand = redir = inc = 0;
  2401. X
  2402. X      while (cont && elast) {
  2403. X         int cstat = cmd_stat(command);
  2404. X
  2405. X         ptr = exarg(&nextstr);
  2406. X         inc = 1;
  2407. X         arg = "";
  2408. X         cont = (elast == 0x80);
  2409. X         switch (*ptr) {
  2410. X         case '<':
  2411. X            redir = -2;
  2412. X         case '>':
  2413. X            if (cstat & (ST_NORED | ST_COND)) {
  2414. X                                                        /* don't extract   */
  2415. X                redir = 0;                              /* <> stuff if its */
  2416. X                arg = ptr;                              /* external cmd.   */
  2417. X                break;
  2418. X            }
  2419. X            ++redir;
  2420. X            arg = ptr + 1;
  2421. X            if (*arg == '>') {
  2422. X               redir = 2;        /* append >> */
  2423. X               ++arg;
  2424. X            }
  2425. X            cont = 1;
  2426. X            break;
  2427. X         case '$':
  2428. X            /* restore args if from set command or pend_alias */
  2429. X            if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) {
  2430. X               if (cstat & ST_COND) {
  2431. X                  char *tp;
  2432. X                  tp = push_cpy(arg);
  2433. X                  arg = tp;
  2434. X               }
  2435. X               else {
  2436. X                  char *pe, sv;
  2437. X                  while (pe = index(arg,0xA0)) {
  2438. X                     sv = *pe;
  2439. X                     *pe = '\0';
  2440. X                     av[ac++] = push_cpy(arg);
  2441. X                     *pe = sv;
  2442. X                     av[ac] = '\0';
  2443. X                     arg = pe+1;
  2444. X                  }
  2445. X               }
  2446. X            }
  2447. X            else
  2448. X               arg = ptr;
  2449. X            break;
  2450. X         case '*':
  2451. X         case '?':
  2452. X            if ((cstat & ST_NOEXP) == 0)
  2453. X               doexpand = 1;
  2454. X            arg = ptr;
  2455. X            break;
  2456. X         default:
  2457. X            arg = ptr;
  2458. X            break;
  2459. X         }
  2460. X
  2461. X         /* Append arg to av[ac] */
  2462. X
  2463. X         for (scr = arg; *scr; ++scr)
  2464. X            *scr &= 0x7F;
  2465. X         if (av[ac]) {
  2466. X            register char *old = av[ac];
  2467. X            av[ac] = mpush(strlen(arg)+strlen(av[ac]));
  2468. X            strcpy(av[ac], old);
  2469. X            strcat(av[ac], arg);
  2470. X         } else {
  2471. X            av[ac] = push_cpy(arg);
  2472. X         }
  2473. X         if (elast != 0x80)
  2474. X            break;
  2475. X      }
  2476. X
  2477. X      /* process expansion */
  2478. X
  2479. X      if (doexpand) {
  2480. X         char **eav, **ebase;
  2481. X         int eac;
  2482. X         has_wild = 1;
  2483. X         eav = ebase = expand(av[ac], &eac);
  2484. X         inc = 0;
  2485. X         if (eav) {
  2486. X            if (ac + eac + 2 > MAXAV) {
  2487. X               ierror (NULL, 506);
  2488. X               err = 1;
  2489. X            } else {
  2490. X               QuickSort(eav, eac);
  2491. X               for (; eac; --eac, ++eav)
  2492. X                  av[ac++] = push_cpy(*eav);
  2493. X            }
  2494. X            free_expand (ebase);
  2495. X         }
  2496. X      }
  2497. X
  2498. X      /* process redirection  */
  2499. X
  2500. X      if (redir && !err) {
  2501. X         register char *file = (doexpand) ? av[--ac] : av[ac];
  2502. X
  2503. X         if (redir < 0)
  2504. X            Cin_name = file;
  2505. X         else {
  2506. X            Cout_name = file;
  2507. X            Cout_append = (redir == 2);
  2508. X         }
  2509. X         inc = 0;
  2510. X      }
  2511. X
  2512. X      /* check elast for space */
  2513. X
  2514. X      if (inc) {
  2515. X         ++ac;
  2516. X         if (ac + 2 > MAXAV) {
  2517. X            ierror (NULL, 506);
  2518. X            err = 1;                /* error condition */
  2519. X            elast = 0;              /* don't process any more arguemnts */
  2520. X         }
  2521. X      }
  2522. X      if (elast == ' ')
  2523. X         goto step5;
  2524. X   }
  2525. Xstepdone:
  2526. X   av[ac] = '\0';
  2527. X
  2528. X   /* process pipes via files */
  2529. X
  2530. X   if (elast == '|' && !err) {
  2531. X      static int which;             /* 0 or 1 in case of multiple pipes */
  2532. X      which = 1 - which;
  2533. X      Cout_name = (which) ? Pipe1 : Pipe2;
  2534. X      Cout_ispipe = 1;
  2535. X   }
  2536. X
  2537. X
  2538. X   if (err)
  2539. X      goto done0;
  2540. X
  2541. X   {
  2542. X      register int i;
  2543. X      char save_elast;
  2544. X      char *compile_av();
  2545. X      register char *avline;
  2546. X      unsigned char delim = ' ';
  2547. X
  2548. X      save_elast = elast;
  2549. X      if (pend_alias || (cmd_stat(command) & ST_AV))
  2550. X         delim = 0xA0;
  2551. X      avline = compile_av(av,((pend_alias) ? 1 : 0), ac , delim);
  2552. X
  2553. X
  2554. X      if (pend_alias) {                               /* special % alias */
  2555. X         register char *ptr, *scr;
  2556. X         for (ptr = pend_alias; *ptr && *ptr != ' '; ++ptr);
  2557. X         set_var (LEVEL_SET, pend_alias + 1, avline);
  2558. X         free (avline);
  2559. X
  2560. X         scr = malloc((strlen(ptr) << 2) + 2);
  2561. X         preformat (ptr, scr);
  2562. X         fcomm (scr, 1);
  2563. X         unset_var (LEVEL_SET, pend_alias + 1);
  2564. X      } else {                                        /* normal command  */
  2565. X         register int ccno;
  2566. X         long  oldcin  = Myprocess->pr_CIS;
  2567. X         long  oldcout = Myprocess->pr_COS;
  2568. X         char *Cin_buf;
  2569. X         struct FileHandle *ci;
  2570. X         long oldbuf;
  2571. X
  2572. X         fflush(stdout);
  2573. X         ccno = find_command (command);
  2574. X         if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
  2575. X            if (Cin_name) {
  2576. X               if ((Cin = (long)extOpen(Cin_name,1005L)) == 0L) {
  2577. X                  ierror (NULL, 504);
  2578. X                  err = 1;
  2579. X                  Cin_name = '\0';
  2580. X               } else {
  2581. X                  Myprocess->pr_CIS = _devtab[stdin->_unit].fd = Cin;
  2582. X                  ci = (struct FileHandle *)(((long)Cin)<<2);
  2583. X                  Cin_buf = (char *)AllocMem(202L, MEMF_PUBLIC);
  2584. X                  oldbuf = ci->fh_Buf;
  2585. X                  if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */
  2586. X                     ci->fh_Buf = (long)Cin_buf>>2;
  2587. X               }
  2588. X            }
  2589. X            if (Cout_name) {
  2590. X               if (Cout_append && (Cout =(long)extOpen(Cout_name, 1005L)) ) {
  2591. X                     Seek(Cout, 0L, 1L);
  2592. X               } else {
  2593. X                  Cout = (long)extOpen(Cout_name,1006L);
  2594. X               }
  2595. X               if (Cout == NULL) {
  2596. X                  err = 1;
  2597. X                  ierror (NULL, 504);
  2598. X                  Cout_name = '\0';
  2599. X                  Cout_append = 0;
  2600. X               } else {
  2601. X                  Myprocess->pr_COS = _devtab[stdout->_unit].fd = Cout;
  2602. X               }
  2603. X            }
  2604. X         }
  2605. X         if (ac < Command[ccno].minargs + 1) {
  2606. X            ierror (NULL, 500);
  2607. X            err = -1;
  2608. X         } else if (!err) {
  2609. X            i = (*Command[ccno].func)(avline, Command[ccno].val);
  2610. X            if (i < 0)
  2611. X               i = 20;
  2612. X            err = i;
  2613. X         }
  2614. X         free (avline);
  2615. X         if (E_stack == 0 && Lastresult != err) {
  2616. X            Lastresult = err;
  2617. X            seterr();
  2618. X         }
  2619. X         if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
  2620. X            if (Cin_name) {
  2621. X               fflush(stdin);
  2622. X               clearerr(stdin);
  2623. X               ci->fh_Buf = oldbuf;
  2624. X               extClose(Cin);
  2625. X               FreeMem(Cin_buf, 202L);
  2626. X            }
  2627. X            if (Cout_name) {
  2628. X               fflush(stdout);
  2629. X               clearerr(stdout);
  2630. X               stdout->_flags &= ~_DIRTY;    /* because of nil: device */
  2631. X               extClose(Cout);
  2632. X               Cout_append = 0;
  2633. X            }
  2634. X         }
  2635. X         Myprocess->pr_CIS =  _devtab[stdin->_unit].fd  = oldcin;
  2636. X         Myprocess->pr_COS =  _devtab[stdout->_unit].fd = oldcout;
  2637. X      }
  2638. X
  2639. X      if (Cin_ispipe && Cin_name)
  2640. X         DeleteFile(Cin_name);
  2641. X      if (Cout_ispipe) {
  2642. X         Cin_name = Cout_name;         /* ok to assign.. static name */
  2643. X         Cin_ispipe = 1;
  2644. X      } else {
  2645. X         Cin_name = '\0';
  2646. X      }
  2647. X      Cout_name = '\0';
  2648. X      Cout_ispipe = 0;
  2649. X      elast = save_elast;
  2650. X   }
  2651. X   mpop_tobase();                      /* free arguments   */
  2652. X   mpush_base();                       /* push dummy base  */
  2653. X
  2654. Xdone0:
  2655. X   {
  2656. X      char *str;
  2657. X      if (err && E_stack == 0) {
  2658. X         str = get_var(LEVEL_SET, v_except);
  2659. X         if (err >= ((str)?atoi(str):1)) {
  2660. X            if (str) {
  2661. X               ++H_stack;
  2662. X               ++E_stack;
  2663. X               exec_command(str);
  2664. X               --E_stack;
  2665. X               --H_stack;
  2666. X            } else {
  2667. X               Exec_abortline = 1;
  2668. X            }
  2669. X         }
  2670. X      }
  2671. X      if (elast != 0 && Exec_abortline == 0)
  2672. X         err = fcomm(nextstr, 0);
  2673. X      Exec_abortline = 0;
  2674. X      if (Cin_name)
  2675. X         DeleteFile(Cin_name);
  2676. X      Cin_name = NULL;
  2677. X      Cin_ispipe = 0;
  2678. X   }
  2679. Xdone1:
  2680. X   mpop_tobase();
  2681. X   if (freeok)
  2682. X      free(str);
  2683. X   --alias_count;
  2684. X   return ((int)err);                  /* TRUE = error occured    */
  2685. X}
  2686. X
  2687. X
  2688. Xchar *
  2689. Xexarg(ptr)
  2690. Xunsigned char **ptr;
  2691. X{
  2692. X   register unsigned char *end;
  2693. X   register unsigned char *start;
  2694. X
  2695. X   start = end = *ptr;
  2696. X   while (*end && *end != 0x80 && *end != ';' && *end != '|' && *end != ' ')
  2697. X      ++end;
  2698. X   elast = *end;
  2699. X   *end = '\0';
  2700. X   *ptr = end + 1;
  2701. X   return ((char *)start);
  2702. X}
  2703. X
  2704. Xstatic char **Mlist;
  2705. X
  2706. Xmpush_base()
  2707. X{
  2708. X   char *str;
  2709. X
  2710. X   str = malloc(5);
  2711. X   *(char ***)str = Mlist;
  2712. X   str[4] = 0;
  2713. X   Mlist = (char **)str;
  2714. X}
  2715. X
  2716. Xchar *
  2717. Xmpush(bytes)
  2718. X{
  2719. X   char *str;
  2720. X
  2721. X   str = malloc(6 + bytes + 2);   /* may need extra 2 bytes in do_run() */
  2722. X   *(char ***)str = Mlist;
  2723. X   str[4] = 1;
  2724. X   Mlist = (char **)str;
  2725. X   return (str + 5);
  2726. X}
  2727. X
  2728. Xmpop_tobase()
  2729. X{
  2730. X   register char *next;
  2731. X   while (Mlist) {
  2732. X      next = *Mlist;
  2733. X      if (((char *)Mlist)[4] == 0) {
  2734. X         free (Mlist);
  2735. X         Mlist = (char **)next;
  2736. X         break;
  2737. X      }
  2738. X      free (Mlist);
  2739. X      Mlist = (char **)next;
  2740. X   }
  2741. X}
  2742. X
  2743. X
  2744. X/*
  2745. X * Insert 'from' string in front of 'str' while deleting the
  2746. X * first entry in 'str'.  if freeok is set, then 'str' will be
  2747. X * free'd
  2748. X */
  2749. X
  2750. Xchar *format_insert_string(str, from, freeok)
  2751. Xchar *str;
  2752. Xchar *from;
  2753. Xint *freeok;
  2754. X{
  2755. Xregister char *new1, *new2;
  2756. Xregister unsigned char *strskip;
  2757. Xint len;
  2758. X
  2759. Xfor (strskip = (unsigned char *)str;
  2760. X        *strskip && *strskip != ' ' 
  2761. X        && *strskip != ';' && *strskip != '|'
  2762. X        && *strskip != 0x80; ++strskip);
  2763. Xlen = strlen(from);
  2764. Xnew1 = malloc((len << 2) + 2);
  2765. Xpreformat(from, new1);
  2766. Xlen = strlen(new1) + strlen(strskip);
  2767. Xnew2 = malloc(len+2);
  2768. Xstrcpy(new2, new1);
  2769. Xstrcat(new2, strskip);
  2770. Xnew2[len+1] = 0;
  2771. Xfree (new1);
  2772. Xif (*freeok) free (str);
  2773. X*freeok = 1;
  2774. Xreturn new2;
  2775. X}
  2776. X
  2777. Xcmd_stat(str)
  2778. Xchar *str;
  2779. X{
  2780. Xreturn(Command[find_command(str)].stat);
  2781. X}
  2782. X
  2783. Xfind_command(str)
  2784. Xchar *str;
  2785. X{
  2786. Xregister unsigned short i;
  2787. Xint len = strlen(str);
  2788. X
  2789. Xfor (i = 0; Command[i].func; ++i)
  2790. X    if ( ! strncmp(str, Command[i].name, len)) return (int)i;
  2791. Xreturn 0;
  2792. X}
  2793. X
  2794. Xdo_help()
  2795. X{
  2796. Xregister struct COMMAND *com;
  2797. Xint i=0;
  2798. X
  2799. Xfor (com = &Command[1]; com->func; ++com) {
  2800. X    printf ("%-12s", com->name);
  2801. X    if (++i % 6 == 0) printf("\n");
  2802. X    }
  2803. Xprintf("\n");
  2804. Xreturn 0;
  2805. X}
  2806. X
  2807. Xchar *push_cpy(s)
  2808. Xchar *s;
  2809. X{
  2810. Xreturn strcpy(mpush(strlen(s)), s);
  2811. X}
  2812. SHAR_EOF
  2813. echo "End of archive 1 (of 2)"
  2814. # if you want to concatenate archives, remove anything after this line
  2815. exit
  2816.